Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to join two different criterias under Hibernate?

I have three tables in my database, a Student, a Classe, and an Assignement. The POJOs are as the following:

Student{
    Classe currentClasse;
    Set<Assignement> assignements;
}

Classe{
    Set<Assignement> assignements;
    SchoolYear schoolYear;
}

Assignement{
    Classe classe;
    Student student;
    Boolean pass;
}

Basically, a student has a current class, and a list of assignements (all the classes he's been assigned to).

My problem is that under hibernate, I'd like to know all the students who do not have a classe (is null) OR who are assigned to a class belonging to the schoolyear "1" but have pass set to true

I managed to make two separate criterias to get what I want:

session.createCriteria(Student.class)
       .add(Restrictions.isNull("classeActuelle"))

and

session.createCriteria(Student.class)
       .createAlias("assignements", "a")
       .add(Restrictions.eq("a.pass", Boolean.TRUE)
       .createAlias("a.classe","c")
       .add(Restrictions.eq("c.schoolYear", "1"))

but I don't know how I can "unite" those two criterias with an or...

like image 864
Simo L. Avatar asked Jun 29 '13 23:06

Simo L.


1 Answers

If you want to create an OR expression with many Criterion objects, you can use an instance of org.hibernate.criterion.Disjunction. Using this object is equivalent to, but more convenient than, using several OR restrictions. To obtain a Disjunction object, call Restrictions.disjunction().

If you need to create an AND expression with many Criterion objects, you can use an object of org.hibernate.criterion.Conjunction. The Restrictions.conjunction() method returns a Conjunction.

The Disjunction and Conjunction classes provide add() methods to apply an OR or an AND, respectively, between the criteria.

Your case:

In your specific case, you can create an outer Disjunction with two Criterion:

  • Students who do not have a class;
  • a Conjunction with two Criterion:
    • Students assigned to a classe belonging to the schoolYear "1";
    • Students that have pass set to true.

Sample code:

The following code uses both the Disjunction and Conjunction objects to construct the necessary criteria.

Criteria c = session.createCriteria(Student.class)
             .createAlias("assignements", "a")
             .createAlias("a.classe","c");

Disjunction or = Restrictions.disjunction();
or.add(Restrictions.isNull("classeActuelle"));

Conjunction and = Restrictions.conjunction();
and.add(Restrictions.eq("a.pass", Boolean.TRUE)
and.add(Restrictions.eq("c.schoolYear", "1"))

or.add(and);

c.add(or);
// you can use your criteria c now
like image 184
acdcjunior Avatar answered Nov 10 '22 08:11

acdcjunior