Que contrôle exactement la stratégie fetch de JPA ? Je ne vois pas de différence entre les stratégies "eager" et "lazy". Dans les deux cas, JPA/Hibernate ne joint pas automatiquement les relations many-to-one.
Exemple : Une personne a une seule adresse. Une adresse peut appartenir à plusieurs personnes. Les classes d'entités annotées JPA ressemblent à ceci :
@Entity
public class Person {
@Id
public Integer id;
public String name;
@ManyToOne(fetch=FetchType.LAZY or EAGER)
public Address address;
}
@Entity
public class Address {
@Id
public Integer id;
public String name;
}
Si j'utilise la requête JPA :
select p from Person p where ...
JPA/Hibernate génère une requête SQL pour sélectionner dans la table Person, puis une requête d'adresse distincte pour chaque personne :
select ... from Person where ...
select ... from Address where id=1
select ... from Address where id=2
select ... from Address where id=3
C'est très mauvais pour les grands ensembles de résultats. S'il y a 1000 personnes, cela génère 1001 requêtes (1 de Personne et 1000 distinctes d'Adresse). Je le sais parce que je regarde le journal des requêtes de MySQL. J'ai cru comprendre qu'en définissant le type de récupération de l'adresse sur eager, JPA/Hibernate effectuera automatiquement une requête avec une jointure. Cependant, quel que soit le type de recherche, il génère toujours des requêtes distinctes pour les relations.
Ce n'est que lorsque je lui demande explicitement de se joindre à moi qu'il le fait :
select p, a from Person p left join p.address a where ...
Est-ce que je rate quelque chose ? Je dois maintenant coder manuellement chaque requête pour qu'elle joigne à gauche les relations plusieurs à un. J'utilise l'implémentation JPA d'Hibernate avec MySQL.
Edit : Il semble (voir la FAQ Hibernate ici y ici ) que FetchType
n'a pas d'incidence sur les requêtes JPA. Dans mon cas, je dois donc lui dire explicitement de se joindre.