Я новичок в спящий режим критериев, соотношение между Tutor
и Student
является OneToMany
(т.е. один Tutor
имеет много Student
), я попытался следующий гибернации запрос для получения всех студентов, чьи Репетитор зовут Питер Смит:Конфликт в результатах между Hibernate Criteria API и Hibernate Query Language
from Student student where student.tutor.name is 'Peter Smith'
и получили следующие результаты:
Shin Don
Robert Cage
, а затем я попытался Hibernate Criteria API для того же запрос следующим образом:
Criteria criteria = session.createCriteria(Student.class);
criteria.createCriteria("tutor").add(Restrictions.eq("name", "Peter Smith"));
criteria.list();
На этот раз я получаю следующий результат:
Shin Don
Shin Don
Robert Cage
Robert Cage
Ниже являются студенческие и Tutor лица у меня есть:
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
}
Для HQL я получаю следующий SQL:
select
...
...
from
Tutor tutor0_
left outer join
Student students1_
on tutor0_.id=students1_.tutor_id
where
tutor0_.id=?
Для критериев, которые я получаю следующий 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=?
Может кто-то помочь мне понять, почему я не получаю то же самое результат для данного HQL и критерии?
Спасибо.
Да, что получил это работает, но Hibernate инструмент по-прежнему дает Шин Дон Шин Дон Роберт Кейдж Роберт Кейджа. Но при тестировании через автономный Java-класс он работает хорошо. Что делать, если у меня не было возможности изменить стратегию 'fetch' в классе Tutor? Почему различное поведение для запросов HQL и Criteria? – skip