【发布时间】:2020-06-04 20:34:24
【问题描述】:
我有以下疑问。我想知道为什么在使用 JPA 和 Hibernate 时,在 ManyToOne 或 OneToMany 关系中执行 Eager 加载时,它会调用 DB 以获取实体信息,但是此外,生成后续查询以获取每个孩子。
另一方面,当使用带有 JOIN FETCH 的查询时,它会按照我的预期执行查询,一次获取所有信息,因为 fetchType 表示为“EAGER”。
这是一个简单的例子:
我的班级学生与班级教室有多对一关系。
@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 对象的 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 子句。
为什么只是在查询中显式添加 Fetch 时,它会按要求执行?
例如:
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
【问题讨论】:
标签: java hibernate jpa eager-loading