简体   繁体   English

为什么在以多对一关系获取数据时执行额外的查询?

[英]Why extra query executed while fetching data in Many to One relationship?

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" 如您在下面的代码中看到的,我编写的HQL查询是:“从“ + Student.class.getName()+中选择学生”,其中student.college.collegeId = 1“

On execution of following code I two SQL queries are fired as follows: 在执行以下代码后,我将按以下方式触发两个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=?

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? 如何通过执行此额外查询来停止Hibernate? 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. 默认情况下, @ManyToOneEAGER ,这意味着从数据库中获取Student时将填充它。 You could set the relation to be LAZY , that would delay that second query until you call student.getCollege() . 您可以将关系设置为LAZY ,这将延迟第二个查询,直到您调用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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM