Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate criteria query on different properties of different objects

Suppose I have classes like:

class A {
 B getB();
 C getC();
}

class B {
 String getFoo();
}

class C {
 int getBar();
}

and I want to filter criteria on A, two filters on different subclass properties, like:

Criteria criteriaA = session.createCriteria(A.class);
Criteria criteriaB = criteriaA.createCriteria("b").add(Restrictions.eq("foo", "Something"));
Criteria criteriaC = criteriaA.createCriteria("c").add(Restrictions.eq("bar", 0));

What I want to do is combine criteriaB and criteriaC using an "or" clause, something like:

//this does not work
criteriaA.add(Restrictions.disjunction().add(criteriaB).add(criteriaC));

How can I accomplish this? I am stumbling a little over the API here.

like image 419
RMorrisey Avatar asked Oct 06 '09 22:10

RMorrisey


People also ask

How do you put restrictions in criteria query?

Restrictions with CriteriaCriteria cr = session. createCriteria(Employee. class); Criterion salary = Restrictions.gt("salary", 2000); Criterion name = Restrictions.

How can we get distinct values in Hibernate criteria?

Criteria crit = session. createCriteria(Test. class); final ResultTransformer trans = new DistinctRootEntityResultTransformer(); crit. setResultTransformer(trans); List rsList = trans.


3 Answers

Use aliases instead of nested criteria:

Criteria criteria = session.createCriteria(A.class)
 .createAlias("b", "b_alias")
 .createAlias("c", "c_alias")
 .add(Restrictions.disjunction()
  .add(Restrictions.eq("b_alias.foo", "Something"))
  .add(Restrictions.eq("c_alias.bar", "0"))
 );
like image 61
ChssPly76 Avatar answered Oct 12 '22 05:10

ChssPly76


You only need to create one criteria object like so.

Criteria criteria = session.createCriteria(A.class);
criteria.add(Restriction.disjunction()
    .add(Restriction.eq("b.foo", "something"))
    .add(Restriction.eq("c.bar", 0)));
like image 42
mR_fr0g Avatar answered Oct 12 '22 05:10

mR_fr0g


In case someone else finds it useful, I found a more complicated answer to the problem which appears to be allowed by the API, though I did not get to test it before ChssPly posted his (simpler) solution:

DetachedCriteria bValues = DetachedCriteria.forClass(A.class);
bValues.createCriteria("b").add(Restrictions.eq("foo", "something"));

DetachedCriteria cValues = DetachedCriteria.forClass(A.class);
cValues.createCriteria("c").add(Restrictions.eq("bar", 0));

Restrictions.or(Subqueries.in("id", bValues), Subqueries.in("id", cValues));
like image 3
RMorrisey Avatar answered Oct 12 '22 07:10

RMorrisey