gpt4 book ai didi

java - JPA 和 Hibernate : Eager loading performing subsequent queries to fetch all data, 而不是在一个查询中完成

转载 作者:行者123 更新时间:2023-12-04 13:57:00 24 4
gpt4 key购买 nike

我有以下疑问。我想知道为什么在使用 JPA 和 Hibernate 时,在 中执行 Eager 加载时多对一 一对多 关系,它调用 DB 以获取实体信息,但另外,生成后续查询以获取每个子项。

另一方面,当使用带有 JOIN FETCH 的查询时,它会按照我的预期执行查询,一次性获取所有信息,因为 fetchType 表示为“EAGER”。

这是一个简单的例子:

我有类(class)学生,它与类(class)教室有多对一关系。

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

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

在另一边有一个名为 Classroom 的类,如下所示:
@Entity
public class Classroom {

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

获取Classroom对象时,执行一次查询从自身获取信息,后续查询获取 中包含的每个学生的信息。学生名单对于每个 classRoom 对象。

第一个查询:
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

最佳答案

因为你有一个 OneToMany关系来自 ClassroomStudent ,使用单个查询会导致 Classroom每行要重复的字段。
现在想象你有第二个 OneToMany关系来自 ClassroomCourse ;如果,对于给定的 Classroom你有 N Student s 和 M Course s,您将有一个返回 N+M 行的查询,每行都包含类 Classroom 的相同字段。 .

关于java - JPA 和 Hibernate : Eager loading performing subsequent queries to fetch all data, 而不是在一个查询中完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60321266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com