0

I am new to Hibernate criteria, the relation between Tutor and Student is OneToMany (i.e. one Tutor has many Student), I tried following hibernate query to retrieve all students whose tutor name is Peter Smith:

from Student student where student.tutor.name is 'Peter Smith'

and got following results:

Shin Don
Robert Cage

and then I tried Hibernate Criteria API for the same query as following:

Criteria criteria = session.createCriteria(Student.class);  
criteria.createCriteria("tutor").add(Restrictions.eq("name", "Peter Smith"));
criteria.list();

This time I get the following result:

Shin Don
Shin Don
Robert Cage 
Robert Cage

Following are the Student and Tutor entities I have:

Student.java

@Entity
public class Student {

    private Integer id;
    private String studentId;
    private String name;
    private Tutor tutor;
    //remaining fields

    public Student() {}
    public Student(String studentId, String name) {
        super();
        this.studentId = studentId;
        this.name = name;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    @Column(unique=true, nullable=false)
    public String getStudentId() {
        return studentId;
    }

    @ManyToOne
    @JoinColumn(name="tutor_id")
    public Tutor getTutor() {
        return tutor;
    }

    @Override
    public int hashCode() {
        //returns hashcode based on studentId
    }
    @Override
    public boolean equals(Object obj) {
        //returns true or false based on studentId
    }
    @Override
    public String toString() {
        return this.name;
    }

    //remaining getter and setter methods

}

Tutor.java

@Entity
public class Tutor{

    private Integer id;
    private String tutorId;
    private String name;
    private Set<Student> students = new HashSet<Student>();
    //remaining fields

    public Tutor() {}   
    public Tutor(String tutorId, String name) {
        super();
        this.tutorId = tutorId;
        this.name = name;
    }

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    @Column(unique=true, nullable=false)
    public String getTutorId() {
        return tutorId;
    }

    @OneToMany(mappedBy="tutor", targetEntity=Student.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    public Set<Student> getStudents() {
        return students;
    }

    @Override
    public int hashCode() {
        //returns hashcode based on tutorId
    }
    @Override
    public boolean equals(Object obj) {
        //returns true or false based on tutorId
    }

    public void addStudent(Student student) {
        this.students.add(student);
        student.setTutor(this);
    }

    //remaining setter and getter methods

}

For HQL I get the following SQL:

select
...
...
from
    Tutor tutor0_ 
left outer join
    Student students1_ 
        on tutor0_.id=students1_.tutor_id 
where
    tutor0_.id=?

For criteria I get the following SQL:

select
...
...
from
    Student this_ 
inner join
    Tutor tutor1_ 
        on this_.tutor_id=tutor1_.id 
left outer join
    Student students4_ 
        on tutor1_.id=students4_.tutor_id 
where
    tutor1_.name=?

Could someone help me understand why am I not getting the same result for the given HQL and criteria?

Thanks.

Mikko Maunu
  • 41,366
  • 10
  • 132
  • 135
skip
  • 12,193
  • 32
  • 113
  • 153

1 Answers1

1

Change in your Tutor.java

     @OneToMany(mappedBy="tutor", targetEntity=Student.class,
cascade=CascadeType.ALL, fetch=FetchType.EAGER)

to

     @OneToMany(mappedBy="tutor", targetEntity=Student.class,
cascade=CascadeType.ALL, fetch=FetchType.LAZY)
Alex
  • 11,451
  • 6
  • 37
  • 52
  • Yes, that got it working but Hibernate Tool's still gives Shin Don Shin Don Robert Cage Robert Cage. But when testing via standalone Java class, it works alright. What if I did not have an option to change the `fetch` strategy in Tutor class? Why different behavior for HQL and Criteria query? – skip Mar 24 '13 at 19:54