2015-01-14 85 views
0

所以,我有以下實體:標準查詢對單向一對多關係

@Entity 
public class Supplier { 
    @Column(name = "SUPPLIERID") 
    private BigInteger supplierId; 

    @OneToMany 
    @JoinColumn(name = "ID_SUPP", foreignKey = @ForeignKey(name = "fk_POIS_SUPP")) 
    private List<POS> posList; 

    ... 
} 

@Entity 
public class POS { 
    @Column(name = "POSID") 
    private BigInteger posId 
} 

所以,POS不具有參考Supplier,這意味着我們有一個單向一對一很多關係。我需要通過posIdsupplierId尋找POS。也就是說,找到具有指定supplierId的供應商,然後在供應商的pos列表中找到具有指定位置的pos。我如何爲此編寫一個標準查詢?

我試過使用子查詢。我的想法是創建一個子查詢,獲取給定supplierId的所有POSSupplier。然後主要查詢將在POSPOS內搜索給定的posId

問題是我無法寫出將獲取Supplier的列表POS s的查詢。顯然,你不能寫List<POS>類型的查詢:

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<POS> outerQuery = cb.createQuery(POS.class); 
Root<POS> outerQueryRoot = outerQuery.from(POS.class); 

Subquery<POS> subquery = outerQuery.subquery(POS.class); 
Root<Supplier> subqueryRoot = subquery.from(Supplier.class); 
subquery.where(cb.equal(subqueryRoot.get(Supplier_.supplierId), supplierId)); 
subquery.select(subqueryRoot.get(Supplier_.posList); 

在最後一行,我得到一個編譯錯誤Expression<POS> does not match Expression<List<POS>>。而且我無法更改子查詢的類型,因爲Java不允許泛型類文字(List<POS>.class)。

任何想法?

回答

2

我終於找到答案,只需使用兩個roots

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
    CriteriaQuery<POS> cq = cb.createQuery(POS.class); 

    Root<POS> posRoot = cq.from(POS.class); 
    Root<Supplier> supplierRoot = cq.from(Supplier.class); 

    cq.where(cb.and(
        cb.equal(supplierRoot.get(Supplier_.suppliertId), supplierId), 
        cb.equal(posRoot.get(POS_.posId), posId))); 
    cq.select(posRoot); 
0

你可以用子查詢來做到這一點。 SQL相當於JPQL 「從POS p其中p.id中(選擇供應商小號sp.id加入s.posList SP,其中s.id =:供應商ID)選擇P」

JPA2 Criteria-API: select... in (select from where)

+0

我無法測試這是否有效,因爲我沒有使用條件查詢的經驗。也許更精通這個主題的人可以提供幫助。 –

+0

您是否關注鏈接?它有一個例子。 – carbontax

+0

我讀了鏈接。但是我不能寫子查詢,它不會編譯。我會詳細解釋這個問題。 –