2011-05-11 102 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 ...)"));