title: JPA Criteria API predicates for objects in OneToMany relationship
body: <p>Given the following code</p>
  
  <pre><code>@Entity
  public class Invoice {
  
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Id
    public Long id;
  
    @Embedded
    private InvoiceData data = new InvoiceData();
  } 
  
  
  @Embeddable
  public class InvoiceData {
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    public Collection&lt;InvoiceLineItem&gt; lineItems;
  }
  
  @Entity
  public abstract class InvoiceLineItem {
  
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
  
    @Column
    private String description;
  }
  
  @Entity
  public class GoodsLineItem extends InvoiceLineItem {
  
  }
  
  @Entity
  public class CostLineItem extends InvoiceLineItem {
  
  }
  </code></pre>
  
  <p>How would I write a criteria api query that returns all Invoices with a CostLinesItem that's description is 'TAX'?</p>
  
  <p>I am using the metadata API. I have tried various approaches most of which are variations of the 2 listed below. Any pointers/help or 'go read this's will be greatly appreciated.</p>
  
  <p>Attempt 1 (of many):</p>
  
  <pre><code>@Test
  public void criteria_api_and_collections() throws Exception {
  
      CriteriaBuilder builder = em.getCriteriaBuilder();
      CriteriaQuery&lt;Invoice&gt; query = builder.createQuery(Invoice.class);
      Root&lt;Invoice&gt; root = query.from(Invoice.class);
  
      Join&lt;InvoiceData, InvoiceLineItem&gt; lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems);
  
      query.where(builder.equal(lineItems.get(InvoiceLineItem_.description), ""));
      List&lt;Invoice&gt; resultList = em.createQuery(query).getResultList();
  
      System.out.println(resultList);
  }
  </code></pre>
  
  <p>Attempt 2 (of a many):</p>
  
  <pre><code>@Test
  public void criteria_api_and_collections() throws Exception {
  
      CriteriaBuilder builder = em.getCriteriaBuilder();
      CriteriaQuery&lt;Invoice&gt; query = builder.createQuery(Invoice.class);
      Root&lt;Invoice&gt; root = query.from(Invoice.class);
  
      Join&lt;InvoiceData, InvoiceLineItem&gt; lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems, JoinType.LEFT);
  
      Subquery&lt;CostLineItem&gt; subquery = query.subquery(CostLineItem.class);
      Root&lt;CostLineItem&gt; fromLineItem = subquery.from(CostLineItem.class);
      subquery.select(fromLineItem);
      subquery.where(builder.equal(lineItems.get(InvoiceLineItem_.description), "TAX"));
  
      query.where(builder.in(lineItems).value(subquery));
  
      List&lt;Invoice&gt; resultList = em.createQuery(query).getResultList();
  }
  </code></pre>
  
  <p>Both attempts causes a SQL grammer Exception. An alias is referred to in the resulting SQL that is never created. It looks like the alias should have been assigned to a join in the SQL that does not exist. In other words the InvoiceLineItems are not fetched in the query.</p>