2011-05-11 78 views
0

我想創建一個「不在」查詢使用休眠標準。我想獲得的所有不知道這種語言的人,所以我有一個看起來像實體:休眠「不在」問題

public class Person { 
    ... 
    private List<Language> languages; 
    ... 
} 

public class Language { 

    public Long id; 
    public String label; 
} 

和我的標準代碼,看起來像

Criteria cr = createCriteriaForPerson() // created criteria 

cr.createCriteria("languages").add(Restrictions.not(Restrictions.in("id", values))); 

這個回報所有的人,包括那些有語言的人。

如果我嘗試搜索具有知道具體語言的人,那麼相當於查詢返回正確的結果

Criteria cr = createCriteriaForPerson() // created criteria 

cr.createCriteria("languages").add(Restrictions.in("id", values)); 

可能是什麼問題呢?

感謝 的Makis

回答

2

我敢肯定,你不能沒有使用sqlRestriction表達標準API此查詢。

幼稚的做法產生了這樣的查詢:

select p from Person p join p.languages l where l.id not in :values 

這顯然不是你想要的,因爲其他語言仍然處於選中狀態。

爲了表達你需要一個複雜的所需的查詢加入

select p from Person p left join p.languages l with l.id in :values where l is null 

或子查詢

select p from Person p where not exists 
    (select l from Language l where l in elements(p.languages) and l.id in :values) 

由於標準API不支持額外的條件加入,來表達此查詢的唯一方法是使用sqlRestriction與子查詢(子查詢的確切形式取決於您的數據庫架構):

cr.add(Restrictions.sqlRestriction(
    "not exists (select ... where l.person_id = {alias}.id and ...)"));