2010-08-30 33 views
1

我遇到了關於JPA-2.0查詢與關係的問題。如何選擇Dataset以及至少一個Eventtype = BJPA-2.0簡單選擇問題

@Entity 
class Dataset { 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "dataset") 
    public List<Event> events; 
} 

@Entity 
class Event { 
    @ManyToOne 
    @JoinColumn 
    public Dataset dataset; 

    public Type type; 
} 

enum Type { 
    A, B, C 
} 

我的出發點是

CriteriaBuilder _builder = em.getCriteriaBuilder(); 
CriteriaQuery<Dataset> _criteria = _builder.createQuery(Dataset.class); 

// select from 
Root<Dataset> _root = _criteria.from(Dataset.class); 
_criteria.select(_root); 

// apply some filter as where-clause (visitor) 
getFilter().apply(
    _root, _criteria, _builder, em.getMetamodel() 
); 

// how to add a clause as defined before? 
... 

的任何想法。我試圖創建一個子查詢以及一個連接,但是我不知何故做錯了,總是得到所有數據集作爲結果。

回答

4

嘗試

SELECT d FROM DataSet d WHERE EXISTS 
    (SELECT e FROM Event e WHERE e.dataSet = d and e.type = :type) 

編輯:正如帕斯卡爾指出,它看起來像你正在使用的標準API。不太熟悉這一點,但我會刺傷。

CriteriaBuilder builder = em.getCriteriaBuilder(); 
CriteriaQuery<Dataset> criteria = builder.createQuery(Dataset.class); 

Root<Dataset> root = criteria.from(Dataset.class); 
criteria.select(root); 

// build the subquery 
SubQuery<Event> subQuery = criteria.subQuery(Event.class); 
Root<Event> eventRoot = subQuery.from(Event.class); 
subQuery.select(eventRoot); 

ParameterExpression<String> typeParameter = builder.parameter(String.class); 
Predicate typePredicate = builder.equal(eventRoot.get(Event_.type), typeParameter)); 

// i have not tried this before but I assume this will correlate the subquery with the parent root entity 
Predicate correlatePredicate = builder.equal(eventRoot.get(Event_.dataSet), root); 
subQuery.where(builder.and(typePredicate, correlatePredicate); 

criteria.where(builder.exists(subQuery))); 

List<DataSet> dataSets = em.createQuery(criteria).getResultList(); 

唉,這是辛苦的工作。我現在要回Linq了。

+0

看起來OP正試圖在這裏使用Criteria API。 – 2010-08-30 19:48:33

+0

謝謝,它爲我工作。我還想出了爲什麼我的方法失敗了。我試圖重用已經執行的查詢並添加了另一個子句。 Hibernate沒有抱怨,但生成了錯誤的別名(主查詢和子查詢具有相同的別名,顯然失敗)。 – Jan 2010-08-31 08:08:46

+0

您需要添加'subquery.select(eventRoot);'以及檢查謂詞'correlatePredicate'的括號。最後'builder.not(builder.exists(subQuery))'應該沒有_not_。非常感謝您的幫助。 – Jan 2010-08-31 08:11:16