eadl:bloc3:dev_av:td2

Ceci est une ancienne révision du document !


# Séance 2 - JPA Avancé et Optimisation (4h)

Contexte : fil rouge e-commerce :

## Objectifs pédagogiques

- Maîtriser les associations bidirectionnelles et leurs pièges - Comprendre et résoudre les problèmes N+1 - Utiliser l'héritage JPA à bon escient - Optimiser les requêtes avec fetch strategies et projections

## Contenu de la séance

### Partie 1 : Associations JPA (1h30)

#### 1.1 Implémentation des associations manquantes

À réaliser : - Compléter `Order` ↔ `OrderItem` (bidirectionnel) - Implémenter `Order` → `User` (unidirectionnel) - Gérer `User` ↔ `Category` (preferences,Many-to-Many) - Ajouter `@JsonIgnore` / `@JsonManagedReference` pour éviter les boucles

Points d'attention : - Choix du côté propriétaire (`mappedBy`) - Cascade types appropriés - Orphan removal - Lazy vs Eager loading

#### 1.2 Exercice pratique : Orders & OrderItems

```java Contraintes métier à implémenter - Un Order doit toujours avoir au moins 1 OrderItem - Suppression d'un Order → suppression des OrderItems - totalAmount calculé automatiquement - Gestion du stock produit lors de la création ``` Tests attendus : - Création d'une commande avec items - Calcul automatique du total - Mise à jour du stock - Suppression en cascade — ### Partie 2 : Problèmes de performance (1h30) #### 2.1 Diagnostic du problème N+1

Scénario : ```java GET /users/{id}/orders Retourne les commandes avec leurs items et produits ``` Mission : 1. Activer les logs SQL (`spring.jpa.show-sql=true`) 2. Identifier le problème N+1 3. Compter le nombre de requêtes générées </WRAP> #### 2.2 Solutions d'optimisation À implémenter et comparer : | Solution | Cas d'usage | Avantages | Inconvénients | |———-|————-|———–|—————| | `@EntityGraph` | Requêtes standards | Simple | Moins flexible | | `JOIN FETCH` | Requêtes complexes | Contrôle total | Code JPQL | | `@BatchSize` | Lazy loading | Transparent | Moins optimal | | DTO Projection | Lecture seule | Performances max | Plus de code | Exercices : 1. Optimiser `/users/{id}/orders` avec JOIN FETCH 2. Créer une projection pour `/products` (liste) 3. Comparer les performances avant/après — ### Partie 3 : Héritage JPA (1h) #### 3.1 Cas d'usage : Typologie de produits

Nouveau besoin métier :

Différencier 3 types de produits : - PhysicalProduct : poids, dimensions, frais de port - DigitalProduct : taille fichier, URL download, format - ServiceProduct : durée, date prestation

Tous partagent : id, name, price, stock, category

#### 3.2 Implémentation avec stratégies d'héritage À explorer (au choix ou comparaison) : ```java Option 1 : SINGLE_TABLE (par défaut) @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = “product_type”)

Option 2 : JOINED @Inheritance(strategy = InheritanceType.JOINED) Option 3 : TABLE_PER_CLASS @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) ```

Exercice comparatif : - Schéma base de données généré - Requêtes SQL produites - Avantages/inconvénients de chaque stratégie

#### 3.3 Requêtes polymorphiques

```java Repository List<Product> findAll(); Tous types confondus List<PhysicalProduct> findPhysicalProducts();

Nouveau endpoint GET /products?type=PHYSICAL GET /products?type=DIGITAL ``` — ## 🎯 Livrables attendus

### Priorités (4h)

Must have : 1. ✅ Associations Order/OrderItem/User complètes avec tests 2. ✅ Résolution problème N+1 sur au moins 2 endpoints 3. ✅ Implémentation héritage produits (1 stratégie au choix) 4. ✅ Tests d'intégration validant les performances

Nice to have : - Comparaison des 3 stratégies d'héritage - DTO Projections avec MapStruct - Benchmark avant/après optimisations - Documentation des choix architecturaux

— ## Critères d'évaluation | Critère | Points | |———|——–| | Associations correctement mappées | 25% | | Résolution problèmes N+1 | 30% | | Implémentation héritage | 25% | | Tests et qualité code | 20% | — ## 🔧 Configuration supplémentaire ```yaml # application.yml - pour la séance spring: jpa: show-sql: true properties: hibernate: format_sql: true use_sql_comments: true generate_statistics: true # Pour mesurer les perfs logging: level: org.hibernate.stat: DEBUG # Statistiques Hibernate ``` — ## Ressources - [Hibernate Performance Best Practices](https://vladmihalcea.com/tutorials/hibernate/) - [Spring Data JPA Query Methods](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods) —

Conseils : - Commencer par les associations avant l'optimisation - Toujours mesurer avant d'optimiser (logs SQL) - L'héritage n'est pas toujours la meilleure solution (composition > héritage) - Privilégier `@ManyToOne` LAZY par défaut

  • eadl/bloc3/dev_av/td2.1759872801.txt.gz
  • Dernière modification : il y a 16 heures
  • de jcheron