2012-02-14 84 views
1

考慮下面的代碼JPA標準API謂詞在一對多關係的對象

@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<InvoiceLineItem> 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 { 

} 

我怎麼會寫一個標準API查詢返回的所有發票與CostLinesItem這說明「稅」?

我正在使用元數據API。我嘗試了各種方法,其中大部分都是下面列出的2的變體。任何指針/幫助或'去讀這將是不勝感激。

嘗試1(許多):

@Test 
public void criteria_api_and_collections() throws Exception { 

    CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Invoice> query = builder.createQuery(Invoice.class); 
    Root<Invoice> root = query.from(Invoice.class); 

    Join<InvoiceData, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems); 

    query.where(builder.equal(lineItems.get(InvoiceLineItem_.description), "")); 
    List<Invoice> resultList = em.createQuery(query).getResultList(); 

    System.out.println(resultList); 
} 

嘗試圖2(a許多的):

@Test 
public void criteria_api_and_collections() throws Exception { 

    CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Invoice> query = builder.createQuery(Invoice.class); 
    Root<Invoice> root = query.from(Invoice.class); 

    Join<InvoiceData, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems, JoinType.LEFT); 

    Subquery<CostLineItem> subquery = query.subquery(CostLineItem.class); 
    Root<CostLineItem> 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<Invoice> resultList = em.createQuery(query).getResultList(); 
} 

兩者的嘗試導致SQL語法異常。在生成的SQL中引用別名是永遠不會創建的。它看起來應該被分配給SQL中不存在的連接。換句話說,InvoiceLineItems不會在查詢中獲取。

回答

0

我無法進行測試的權利,但堅持到Java EE 6 Tutorial,我們看到

嵌入類也可以包含到其他實體或實體的 集合的關係。如果可嵌入類具有這種關係,則該關係是從實體的目標實體或集合 到擁有可嵌入類的實體。

這讓我覺得Join謂語應與實體開始,而不是InvoiceInvoiceData定義。這也得益於通常起始實體應該是查詢根本身的事實。我會嘗試這樣的事情:

Join<Invoice, InvoiceLineItem> lineItems = root.join(Invoice_.data).join(InvoiceData_.lineItems); 
+0

謝謝你的信息。除非我誤解它,現在正如建議的那樣(不包括鬥爭期間添加的JoinType.LEFT)? – fransvn 2012-02-20 20:13:39

0

我換出了EclipseLink 2.0.0的Hibernate 4.1.0.Final,它工作。