Bateau
qui possède un équipage, stocké sous forme d'une collection de
Marin
.
Une manière naïve de lire un bateau en base, serait de lire ce bateau avec une requête
SELECT
, et de laisser la collection de marins vide. Si l'application explore la relation
marins
, par itération ou autre, alors un deuxième
SELECT
est émis, qui peuple la relation de façon à faire fonctionner le système correctement. Au total, deux
SELECT
sont émis, donc deux allers-retours avec la base de données.
Dans le cas où l'on sait que la relation
marins
sera explorée systématiquement après la lecture d'un bateau, il serait plus malin de n'émettre qu'un seul
SELECT
, avec une jointure, de manière à peupler la relation
marins
à l'avance. Cela ne ferait qu'un seul aller-retour avec la base de données, et serait de ce fait beaucoup plus performant.
En revanche, dans le cas d'une relation qui, pour des raisons applicatives, ne serait pas explorée, ou rarement, alors l'exécution de la jointure lors du
SELECT
serait un surcoût inutile.
JPA nous permet de régler, relation par relation, la façon dont il doit se comporter :
fetch
, défini sur les annotations
@OneToOne
,
@OneToMany
,
@ManyToOne
et
@ManyToMany
. Cet attribut peut prendre deux valeurs :
FetchType.LAZY
: indique que la relation doit être chargée à la demande ;
FetchType.EAGER
: indique que la relation doit être chargée en même temps que l'entité qui la porte.
Exemple 16. Utilisation de
fecth
sur une relation
@Entity public class Bateau implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @OneToMany(fetch=FetchType.EAGER) // la relation est chargée par défaut private Collection<Marin> marins ; // reste de la classe }