У меня есть следующие сомнения. Я хотел бы знать, почему при использовании JPA и Hibernate при выполнении загрузки Eager в отношениях ManyToOne или OneToMany он вызывает DB для получения информации о сущности, но дополнительно: производит последующие запросы для извлечения каждого ребенка.
С другой стороны, при использовании запроса с JOIN FETCH он выполняет запрос, как я и ожидал, принимая информацию сразу, поскольку fetchType обозначается как «EAGER».
Вот простой пример:
У меня есть ученик класса, у которого есть отношения ManyToOne с классной комнатой.
@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 он выполняет один запрос для получения информации от себя и последующие запросы для получения информации о каждом ученике, содержащейся в StudentsList для каждого 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 там .
Почему просто при явном добавлении 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