Reputation: 1195
I am trying to create a "not in" query using hibernate Criteria. What I am trying to get is all the persons that don't know this language, so I have an entity that looks like:
public class Person {
...
private List<Language> languages;
...
}
public class Language {
public Long id;
public String label;
}
and my criteria code that looks like
Criteria cr = createCriteriaForPerson() // created criteria
cr.createCriteria("languages").add(Restrictions.not(Restrictions.in("id", values)));
this returns all the persons including the ones that have the language.
If I try to search for the persons that have know the specific language, then the equivalent query returns the correct results
Criteria cr = createCriteriaForPerson() // created criteria
cr.createCriteria("languages").add(Restrictions.in("id", values));
What could be the problem?
Thanks Makis
Upvotes: 0
Views: 2705
Reputation: 242726
I'm pretty sure that you cannot express this query in Criteria API without using sqlRestriction
.
Naive approach produces a query like this:
select p from Person p join p.languages l where l.id not in :values
It's obviously not what you want since other languages are still selected.
To express the desired query you need a complex join
select p from Person p left join p.languages l with l.id in :values where l is null
or subquery
select p from Person p where not exists
(select l from Language l where l in elements(p.languages) and l.id in :values)
Since Criteria API doesn't support joins with extra conditions, the only way to express this query is to use sqlRestriction
with a subqery (exact form of the subqery depends on your database schema):
cr.add(Restrictions.sqlRestriction(
"not exists (select ... where l.person_id = {alias}.id and ...)"));
Upvotes: 2