I want to write a hibernate criteria that excludes certain entities. Here's what I have so far:
Criterion exclusion1 = Restrictions.not(Restrictions.conjunction()
.add(Restrictions.eq("color", "blue");
.add(Restrictions.eq("type", "aaa"))
.add(Restrictions.eq("subtype1", "bbb"))
.add(Restrictions.eq("subtype2", "ccc"));
Criteria crit = session.createCriteria(MyObject.class);
crit.add(exclusion1);
List result = crit.list();
There are several such exclusion criterion. This seems to do what I want except that if any of the fields are null I want it to be included. e.g an entity with color = blue, type = aaa, subtype1 and subtype2 are null to be included.
How can I rewrite this to not exclude that entity?
Here's something that works the way I want.
From this answer, it seems that the proper way to do this is to use a subquery to define what should be excluded. e.g.
Criterion exclusion1 = Restrictions.conjunction()
.add(Restrictions.eq("color", "blue"))
.add(Restrictions.eq("type", "aaa"))
.add(Restrictions.eq("subtype1", "bbb"))
.add(Restrictions.eq("subtype2", "ccc"));
Criterion exclusion2 = Restrictions.conjunction()
.add(Restrictions.eq("color", "blue"))
.add(Restrictions.eq("type", "ddd"))
.add(Restrictions.eq("subtype1", "eee"));
DetachedCriteria excludes = DetachedCriteria.forClass(MyObject.class)
.add(Restrictions.disjunction()
.add(exclusion1)
.add(exclusion2))
.setProjection(Projections.property("id"));
Criteria crit = session.createCriteria(MyObject.class);
crit.add(Restrictions.eq("state","ok"));
crit.add(Property.forName("id").notIn(excludes));
List results = crit.list();
I'm still interested in knowing if there's a better way, but this seems pretty good.