| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente |
| framework-web:spring:relations [2025/10/08 00:59] – [Performance : Unidirectionnel vs Bidirectionnel] jcheron | framework-web:spring:relations [2025/10/08 01:24] (Version actuelle) – [Schéma de base de données] jcheron |
|---|
| ====== Relations JPA ====== | ====== Relations JPA ====== |
| |
| ===== Les Types de Relations ===== | ===== Types de Relations ===== |
| |
| ==== @OneToMany / @ManyToOne ==== | ==== @OneToMany / @ManyToOne ==== |
| Cas d'usage : Un auteur a plusieurs livres, un livre a un seul auteur. | Cas d'usage : Un auteur a plusieurs livres, un livre a un seul auteur. |
| |
| === Configuration Unidirectionnelle (❌ Rarement recommandée) === | === Configuration Unidirectionnelle (🟰 Rarement recommandée) === |
| <sxh java> | <sxh java> |
| @Entity | @Entity |
| @Entity | @Entity |
| public class Author { | public class Author { |
| @OneToMany(mappedBy = "author") // ❌ N'est PAS le owner | @OneToMany(mappedBy = "author") // ❌ Non owner |
| private List<Book> books; | private List<Book> books; |
| } | } |
| public class Book { | public class Book { |
| @ManyToOne | @ManyToOne |
| @JoinColumn(name = "author_id") // ✅ EST le owner | @JoinColumn(name = "author_id") // ✅ Owner |
| private Author author; | private Author author; |
| } | } |
| id BIGINT PRIMARY KEY, | id BIGINT PRIMARY KEY, |
| title VARCHAR(255), | title VARCHAR(255), |
| author_id BIGINT, -- ← LA CLÉ ÉTRANGÈRE EST ICI ! | author_id BIGINT, |
| CONSTRAINT fk_author FOREIGN KEY (author_id) REFERENCES author(id) | CONSTRAINT fk_author FOREIGN KEY (author_id) REFERENCES author(id) |
| ); | ); |
| </sxh> | </sxh> |
| |
| <code sql> | <sxh sql> |
| SELECT * FROM book; -- Requête 1 | SELECT * FROM book; -- Requête 1 |
| SELECT * FROM author WHERE id = 1; -- Requête 2 | SELECT * FROM author WHERE id = 1; -- Requête 2 |
| SELECT * FROM author WHERE id = 3; -- Requête 4 | SELECT * FROM author WHERE id = 3; -- Requête 4 |
| ... | ... |
| </code> | </sxh> |
| |
| === Solution 1 : JOIN FETCH === | === Solution 1 : JOIN FETCH === |
| </sxh> | </sxh> |
| |
| <code sql> | <sxh sql> |
| -- ✅ Une seule requête ! | -- ✅ Une seule requête ! |
| SELECT b.*, a.* | SELECT b.*, a.* |
| FROM book b | FROM book b |
| INNER JOIN author a ON b.author_id = a.id; | INNER JOIN author a ON b.author_id = a.id; |
| </code> | </sxh> |
| |
| === Solution 2 : @EntityGraph === | === Solution 2 : @EntityGraph === |
| </sxh> | </sxh> |
| |
| <code sql> | <sxh sql> |
| SELECT * FROM author; -- Requête 1 | SELECT * FROM author; -- Requête 1 |
| |
| SELECT id FROM author | SELECT id FROM author |
| ); | ); |
| </code> | </sxh> |
| |
| ==== LazyInitializationException ==== | ==== LazyInitializationException ==== |
| |
| ''application.properties'' : | ''application.properties'' : |
| <code> | <sxh bash> |
| # Afficher les requêtes SQL | # Afficher les requêtes SQL |
| spring.jpa.show-sql=true | spring.jpa.show-sql=true |
| # Détecter le problème N+1 | # Détecter le problème N+1 |
| spring.jpa.properties.hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=10 | spring.jpa.properties.hibernate.session.events.log.LOG_QUERIES_SLOWER_THAN_MS=10 |
| </code> | </sxh> |
| |
| |