🎬 Passer en mode présentation

Hibernate — Relations, Mapping et Fetch


1. Les relations entre deux tables

Règle de la spécification JPA (respectée par Hibernate) :

  • Les associations vers une seule entité (to-one) sont EAGER par défaut
  • Les collections (to-many) sont LAZY par défaut

Il faut éviter autant que possible les relations bidirectionnelles

Tableau des relations (annotations JPA / balises HBM)

Annotation JPA Balise HBM Cardinalité Fetch par défaut Peut être LAZY ?
@ManyToOne <many-to-one> N – 1 EAGER ✅ Oui — lazy="proxy" (défaut HBM)
@OneToOne (owning side) <one-to-one constrained="true"> 1 – 1 EAGER ✅ Oui — proxy possible car FK contrainte
@OneToOne (inverse mappedBy) <one-to-one constrained="false"> 1 – 1 EAGER Non — LAZY impossible par nature
@OneToMany <one-to-many> dans <set> 1 – N LAZY ✅ Déjà LAZY par défaut
@ManyToMany <many-to-many> dans <set> N – N LAZY ✅ Déjà LAZY par défaut

2. @OneToOne inverse

C'est la limitation structurelle la plus importante. Avec constrained="false" (ou mappedBy côté JPA), Hibernate ne sait pas a priori si la ligne associée existe en base. Pour créer un proxy, Hibernate est obligé d'émettre une requête immédiate pour le vérifier.

Hibernate :

"Note that if constrained="false", proxying is impossible and Hibernate will eagerly fetch the association."

La seule solution pour forcer le LAZY sur ce cas est d'activer le Bytecode Enhancement :

<enableLazyInitialization>true</enableLazyInitialization>
La seule solution pour forcer le LAZY sur ce cas est d'activer le Bytecode Enhancement :
<enableLazyInitialization>true</enableLazyInitialization>
Si on doit utiliser le Bytecode Enhancement alors il faudra approfondir ce point et compléter cette section

un proxy hibernate

Un proxy hibernate est un objet qui encapsule l'objet réel et qui permet de retarder le chargement de l'objet.

L'objet proxy est l'objet lui-même mais il ne contient que son identifiant.

Sans identifiant, il ne peut donc créer un proxy

Il a donc besoin de savoir si l'objet existe en base de données avant de pouvoir le charger.


3. Valeurs de l'attribut lazy en HBM

Pour <many-to-one> et <one-to-one constrained="true"> :

Valeur Comportement
lazy="proxy" Défaut — crée un proxy Hibernate, requête émise à l'accès
lazy="no-proxy" Lazy sans proxy — nécessite le Bytecode Enhancement
lazy="false" EAGER — chargement immédiat

Pour les collections (<set>, <list>, …) :

Valeur Comportement
lazy="true" Défaut — collection chargée à l'accès
lazy="false" EAGER — chargement immédiat avec la requête parente
lazy="extra" Smart lazy — count() et contains() sans charger toute la collection

4. Bonnes pratiques sur le Fetch

Recommandation officielle Hibernate :

"Marquer toutes les associations en LAZY statiquement, puis définir les stratégies de chargement dynamiquement selon les besoins via JPQL JOIN FETCH ou @EntityGraph.

Eviter EAGER par défaut

Problème Description
N+1 requêtes Chaque entité chargée déclenche autant de requêtes que d'associations EAGER
Produit cartésien Plusieurs @ManyToMany en EAGER génèrent un produit cartésien explosif
Chargement inutile Des données sont chargées même quand le cas d'usage n'en a pas besoin(ou dans l'autre sens de la relation)

Exemple :

// ❌ À éviter : EAGER statique
@ManyToOne(fetch = FetchType.EAGER)
private Customer customer;

// ✅ Recommandé : LAZY statique 
@ManyToOne(fetch = FetchType.LAZY)
private Customer customer;

// JOIN FETCH dynamique
"SELECT o FROM Order o JOIN FETCH o.customer WHERE o.id = :id"

5. Références

Ressource URL
Hibernate 5.3 User Guide — Associations https://docs.hibernate.org/orm/5.3/userguide/html_single/#associations
Hibernate 5.3 User Guide — Fetching https://docs.hibernate.org/orm/5.3/userguide/html_single/#fetching
Hibernate 3.3 Reference — Basic O/R Mapping (HBM) https://docs.hibernate.org/orm/3.3/reference/en/html/mapping.html
Hibernate 3.3 Reference — Collections (lazy HBM) https://docs.hibernate.org/orm/3.3/reference/en/html/collections.html
FetchType Lazy/Eager — Thorben Janssen https://thorben-janssen.com/entity-mappings-introduction-jpa-fetchtypes/
Mapping Definitions JPA/Hibernate (Annotations vs XML) — Thorben Janssen https://thorben-janssen.com/mapping-definitions-jpa-hibernate-annotations-xml/
A beginner's guide to Hibernate fetching strategies — Vlad Mihalcea https://vladmihalcea.com/hibernate-facts-the-importance-of-fetch-strategy/

Terminé