为什么在多对一关系中获取数据时执行额外查询? [英] Why extra query executed while fetching data in Many to One relationship?
问题描述
@Entity
公共类学院{
@ Id
@GeneratedValue
private int collegeId;
private String collegeName;
public int getCollegeId(){
return collegeId;
}
public void setCollegeId(int collegeId){
this.collegeId = collegeId;
}
public String getCollegeName(){
return collegeName;
}
public void setCollegeName(String collegeName){
this.collegeName = collegeName;
}
}
@实体
公共类学生{
@Id
@GeneratedValue
private int studentId;
private String studentName;
@ManyToOne(cascade = CascadeType.ALL)
私立大专院校;
public int getStudentId(){
return studentId;
}
public void setStudentId(int studentId){
this.studentId = studentId;
}
public String getStudentName(){
return studentName;
}
public void setStudentName(String studentName){
this.studentName = studentName;
}
public College getCollege(){
return college;
}
public void setCollege(College college){
this.college = college;
}
}
我想要取得某所大学的所有学生。
正如你在下面的代码中看到的,我写的HQL查询是:select student from+ Student.class.getName()+student where student。 college.collegeId = 1
在执行下面的代码时,我按如下方式触发两个SQL查询:
Hibernate:select student0_.studentId as studentId1_1_,student0_.college_collegeId as college_collegeId3_1_,student0_.studentName as studentName2_1_ from mevada.Student student0_ where student0_.college_collegeId = 1
Hibernate:select college0_.collegeId as collegeId1_0_0_,college0_.collegeName as collegeName2_0_0_ from mevada.College college0_ where college0_.collegeId =?
理想情况下,第一个查询足以获取所有需要的学生,并且当我直接从数据库。
为什么执行第二个查询?如何通过执行这个额外的查询来阻止Hibernate?
工具类:
public class ManyToOne {
public static void main(String [ ] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory(org.hibernate.examples);
EntityManager em = emf.createEntityManager();
大学学院1 =新学院();
college1.setCollegeName(College1);
大专院校2 =新大学();
college2.setCollegeName(College2);
学生student1 =新生Student();
student1.setStudentName(std1);
student1.setCollege(college1);
学生student2 =新生Student();
student2.setStudentName(std2);
student2.setCollege(college2);
Student student3 = new Student();
student3.setStudentName(std3);
student3.setCollege(college1);
学生student4 =新生Student();
student4.setStudentName(std4);
student4.setCollege(college1);
em.getTransaction()。begin();
em.persist(college1);
em.persist(college2);
em.persist(student1);
em.persist(student2);
em.persist(student3);
em.persist(student4);
em.getTransaction()。commit();
em.close();
em = emf.createEntityManager();
em.getTransaction()。begin();
String queryString =select student from+ Student.class.getName()+student where student.college.collegeId = 1;
查询查询= em.createQuery(queryString);
列表< Student> students = query.getResultList();
em.getTransaction()。commit();
em.close();
emf.close();
$ b
这是因为
@ManyToOne(cascade = CascadeType.ALL)
私立大学学院;
@ManyToOne
是 EAGER
,这意味着当从数据库中获取 Student
时,它会被填充。您可以将关系设置为 LAZY
,这会延迟第二个查询,直到您调用 student.getCollege()
。但是,如果你知道你还需要大学数据,你应该能够像这样在一个查询中得到它。
select student from+ Student.class.getName()+student inner join student.college col where col.collegeId = 1
I have two entities student and college. A single college has multiple student.
@Entity
public class College {
@Id
@GeneratedValue
private int collegeId;
private String collegeName;
public int getCollegeId() {
return collegeId;
}
public void setCollegeId(int collegeId) {
this.collegeId = collegeId;
}
public String getCollegeName() {
return collegeName;
}
public void setCollegeName(String collegeName) {
this.collegeName = collegeName;
}
}
@Entity
public class Student {
@Id
@GeneratedValue
private int studentId;
private String studentName;
@ManyToOne(cascade = CascadeType.ALL)
private College college;
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public College getCollege() {
return college;
}
public void setCollege(College college) {
this.college = college;
}
}
I want to fetch all the students of a particular college.
As you can see in below code the HQL query I have written is : "select student from "+Student.class.getName()+" student where student.college.collegeId = 1"
On execution of following code I two SQL queries are fired as follows:
Hibernate: select student0_.studentId as studentId1_1_, student0_.college_collegeId as college_collegeId3_1_, student0_.studentName as studentName2_1_ from mevada.Student student0_ where student0_.college_collegeId=1
Hibernate: select college0_.collegeId as collegeId1_0_0_, college0_.collegeName as collegeName2_0_0_ from mevada.College college0_ where college0_.collegeId=?
Ideally first query is sufficient to fetch all required students and it is working well when I fire directly from database.
why second query is executed? How can I stop Hibernate by executing this extra query? Utility class:
public class ManyToOne {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.hibernate.examples");
EntityManager em = emf.createEntityManager();
College college1 = new College();
college1.setCollegeName("College1");
College college2 = new College();
college2.setCollegeName("College2");
Student student1 = new Student();
student1.setStudentName("std1");
student1.setCollege(college1);
Student student2 = new Student();
student2.setStudentName("std2");
student2.setCollege(college2);
Student student3 = new Student();
student3.setStudentName("std3");
student3.setCollege(college1);
Student student4 = new Student();
student4.setStudentName("std4");
student4.setCollege(college1);
em.getTransaction().begin();
em.persist(college1);
em.persist(college2);
em.persist(student1);
em.persist(student2);
em.persist(student3);
em.persist(student4);
em.getTransaction().commit();
em.close();
em = emf.createEntityManager();
em.getTransaction().begin();
String queryString = "select student from "+Student.class.getName()+" student where student.college.collegeId = 1";
Query query = em.createQuery(queryString);
List<Student> students = query.getResultList();
em.getTransaction().commit();
em.close();
emf.close();
}
}
It's because of this
@ManyToOne(cascade = CascadeType.ALL)
private College college;
@ManyToOne
is EAGER
by default, which means it is populated when Student
is fetched from database. You could set the relation to be LAZY
, that would delay that second query until you call student.getCollege()
. But if you know you'll need college data as well, you should be able to get it all in one query like this
"select student from " + Student.class.getName() + " student inner join student.college col where col.collegeId = 1"
这篇关于为什么在多对一关系中获取数据时执行额外查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!