🎬 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` | `
` | N – 1 | **EAGER** | ✅ Oui — `lazy="proxy"` (défaut HBM) | | `@OneToOne` (owning side) | `
` | 1 – 1 | **EAGER** | ✅ Oui — proxy possible car FK contrainte | | `@OneToOne` (inverse `mappedBy`) | `
` | 1 – 1 | **EAGER** | ❌ **Non — LAZY impossible par nature** | | `@OneToMany` | `
` dans `
` | 1 – N | **LAZY** | ✅ Déjà LAZY par défaut | | `@ManyToMany` | `
` dans `
` | 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** : ```xml
true
``` ### 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 `
` et `
` : | 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 (`
`, `
`, …) : | 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 : ```java // ❌ À é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é