当前位置: 首页 > 知识库问答 >
问题:

JPA&Hibernate:热切加载执行后续查询以获取所有数据,而不是只在一个查询中执行

阴靖
2023-03-14

我有以下疑问。我想知道为什么在使用JPA和Hibernate时,在ManyToOne或OneToMany关系中执行热切加载时,它会调用DB以获取实体信息,但另外,还会生成后续查询以获取每个子级。

另一方面,当使用带有JOIN FETCH的查询时,它会像我所期望的那样执行查询,同时获取所有信息,因为fetchType被表示为“Eager”。

这里是一个简单的例子:

我有一个和班级教室有很多关系的班级学生。

@Entity
@Table(name = "STUDENT")
public class Student {

@ManyToOne(optional = true, fetch = FetchType.EAGER)
        @JoinColumn(name = "ClassroomID")
        private Classroom mainClass;

在另一边有一个名为教室的班级,如下所示:

@Entity
public class Classroom {

@OneToMany(cascade = CascadeType.ALL, mappedBy = "mainClass", fetch = FetchType.EAGER)
private List<Student> studentsList;

第一个查询:

Hibernate: 
/* SELECT
         r 
     FROM
         Classroom r 
     LEFT JOIN
         r.classStudents */ 

     select
         classroom0_.id as id1_0_,
         classroom0_.number as number2_0_ 
     from
         Classroom classroom0_ 
     left outer join
         STUDENT classstude1_ 
             on classroom0_.id=classstude1_.ClassroomID

然后,它执行下一个查询的次数与分配到每个教室的学生的次数一样多。

  Hibernate: 
      /* load one-to-many com.hw.access.Classroom.classStudents */ 
      select
          classstude0_.ClassroomID as Classroo4_0_1_,
          classstude0_.id as id1_1_1_,
          classstude0_.id as id1_1_0_,
          classstude0_.FIRST_NAME as FIRST_NA2_1_0_,
          classstude0_.LAST_NAME as LAST_NAM3_1_0_,
          classstude0_.ClassroomID as Classroo4_1_0_ 
      from
          STUDENT classstude0_ 
      where
          classstude0_.ClassroomID=?

问题是:为什么它不一次获取所有信息?为什么它不在一个查询中获取信息?因为它已经在那里执行Join子句。

SELECT
         r 
     FROM
         Classroom r 
     LEFT JOIN FETCH
         r.classStudents */ 
Hibernate: 

        select
              classroom0_.id as id1_0_0_,
              classstude1_.id as id1_1_1_,
              classroom0_.number as number2_0_0_,
              classstude1_.FIRST_NAME as FIRST_NA2_1_1_,
              classstude1_.LAST_NAME as LAST_NAM3_1_1_,
              classstude1_.ClassroomID as Classroo4_1_1_,
              classstude1_.ClassroomID as Classroo4_0_0__,
              classstude1_.id as id1_1_0__ 
          from
              Classroom classroom0_ 
          left outer join
              STUDENT classstude1_ 
                  on classroom0_.id=classstude1_.ClassroomID

共有1个答案

邵宜年
2023-03-14

由于您有从classorystudentonetomany关系,因此使用单个查询将导致对每一行重复classory字段。现在假设您有第二个onetomany关系,从教室到,比如说课程;如果对于给定的教室有N个学生和M个课程,则查询将返回N+M行,每个行包含教室类的相同字段。

 类似资料:
  • 问题内容: 关于我之前的问题,我想确保所有子对象都已加载,因为我有多个线程可能需要访问数据(从而避免延迟加载异常)。我知道执行此操作的方法是在查询(EJB QL)中使用“fetch”关键字。像这样: 假设模型中包含一个类。 我的问题是,似乎需要“ distinct”关键字,否则我似乎会为每个关键字找回一个。我做对了吗? 也许更重要的是,是否有一种方法可以拉入所有子对象,无论深度如何?我们大约有10

  • 假设spring boot中有一个名为Person的类,其结构如下 人由一组电话号码组成。 是一个由上述字段组成的类,其中类别表示或等。 因此,每当我想要获取带有一些的详细信息时,我都会调用上面的方法,然后它应该获取详细信息,以及,其是。 方法应该是每当它在内部执行方法的查询时,它应该执行后续的查询来获取类别为的。我有没有办法得到上面提到的,或者有没有其他方法来实现它?请让我知道。 PS:如果在我

  • 问题内容: 我有一个带有库的IntelliJ项目:Hibernate-entitymanager 4.3.4和JPA 2.0-2.0。使用postgresql-9.3.1100.jdbc4连接到数据库。如何解决? jpa-ql>从ItemEntity中选择ItemEntity.name; 问题答案: 只需阅读文档: http://docs.oracle.com/javaee/7/api/javax

  • 问题陈述:在JPA hibernate中,我执行了一个方法

  • 我希望在一个select请求中运行以下查询: 问题是所有内容都是由单独的多个查询获取的。我只希望团队和团队的球员和每个球员的技能在一个请求中被获取。但是相反,我有多个选择查询来获取每个团队、玩家、每个玩家的统计数据和技能。 以下是与注释一起使用的实体: 游戏实体: 团队实体: 玩家实体: 你能指出所犯的错误吗?我需要一个选择查询来加载游戏,它是团队、团队的球员和每个球员的技能。 编辑1:以下是po