J'ai le doute suivant. J'aimerais savoir pourquoi, en utilisant JPA et Hibernate, lorsqu'on effectue un chargement Eager dans une base de données de type ManyToOne o OneToMany il appelle la base de données afin d'obtenir les informations sur l'entité, mais il produit en outre des requêtes ultérieures pour récupérer chaque enfant.
D'un autre côté, lorsqu'on utilise une requête avec JOIN FETCH, la requête est exécutée comme je m'y attendais, en prenant les informations en une seule fois, puisque le fetchType est indiqué comme "EAGER".
Voici un exemple simple :
J'ai la classe Student qui a une relation ManyToOne avec la classe Classroom.
@Entity
@Table(name = "STUDENT")
public class Student {
@ManyToOne(optional = true, fetch = FetchType.EAGER)
@JoinColumn(name = "ClassroomID")
private Classroom mainClass;
De l'autre côté, il y a la classe nommée Classroom comme suit :
@Entity
public class Classroom {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "mainClass", fetch = FetchType.EAGER)
private List<Student> studentsList;
Lorsqu'il obtient l'objet Salle de classe, il effectue une requête pour obtenir les informations le concernant et des requêtes ultérieures pour obtenir les informations de chaque élève contenu dans l'objet liste des étudiants pour chaque objet classRoom.
Première requête :
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
Puis il exécute la requête suivante autant de fois que d'étudiants affectés à chaque classe.
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=?
La question est la suivante : Pourquoi ne prend-il pas les informations en une seule fois ? Pourquoi ne prend-il pas les informations en une seule requête ? Comme il exécute déjà la clause de jonction .
Pourquoi juste en ajoutant Aller chercher explicitement dans la requête, il fait ce qui lui est demandé ?
Par exemple :
SELECT
r
FROM
Classroom r
LEFT JOIN FETCH
r.classStudents */
Et ensuite, la requête de sortie reprend toutes les informations en une seule requête :
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