【问题标题】:Why extra query executed while fetching data in Many to One relationship?为什么在多对一关系中获取数据时执行额外的查询?
【发布时间】:2015-02-14 22:56:31
【问题描述】:

我有两个实体学生和大学。一所大学有多名学生。

@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;
    }
}

我想获取特定学院的所有学生。

正如您在下面的代码中看到的,我编写的 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();

        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();

    }
}

【问题讨论】:

    标签: java hibernate orm


    【解决方案1】:

    因为这个

    @ManyToOne(cascade = CascadeType.ALL)
    private College college;
    

    @ManyToOne 默认为EAGER,这意味着从数据库中获取Student 时会填充它。您可以将关系设置为LAZY,这将延迟第二个查询,直到您调用student.getCollege()。但是,如果您知道自己也需要大学数据,那么您应该能够像这样在一个查询中获得所有数据

    "select student from " + Student.class.getName() + " student inner join student.college col where col.collegeId = 1"
    

    【讨论】:

    • 我将 FetchType 更改为 LAZY,我遇到了这个异常:java.lang.ClassCastException:entities.College_$$_javassist_0 cannot be cast to javassist.util.proxy.Proxy
    • 查看this thread 以获得可能的解决方案。常见的原因似乎是一些依赖问题。
    • 谢谢@Predrag。我已经从同一个线程修复了异常。没有时间提及同样的事情。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 2010-11-25
    • 2011-12-27
    • 2021-01-30
    • 2014-11-06
    相关资源
    最近更新 更多