eadl:bloc3:dev_av:td2

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
eadl:bloc3:dev_av:td2 [2025/10/07 23:40] – [Configuration supplémentaire] jcheroneadl:bloc3:dev_av:td2 [2025/10/08 00:18] (Version actuelle) – [4.4 Optimisation des identifiants avec Tsid] jcheron
Ligne 126: Ligne 126:
 </sxh> </sxh>
  
-===== Livrables attendus =====+===== Partie 4 : Hypersistence Utils - Outils avancés (30min-1h) ===== 
 + 
 +==== 4.1 Introduction à Hypersistence Utils ==== 
 + 
 +<WRAP round bloc info> 
 +**Hypersistence Utils** est une bibliothèque créée par Vlad Mihalcea qui apporte : 
 +  * Des types personnalisés (JSON, Array, etc.) 
 +  * Des utilitaires de diagnostic de performance 
 +  * Des listeners pour optimiser les opérations 
 +  * Des identifiants optimisés (Tsid) 
 +</WRAP> 
 + 
 +=== Dépendance Maven === 
 + 
 +<sxh xml;gutter:false> 
 +<dependency> 
 +    <groupId>io.hypersistence</groupId> 
 +    <artifactId>hypersistence-utils-hibernate-63</artifactId> 
 +    <version>3.7.0</version> 
 +</dependency> 
 +</sxh> 
 + 
 +==== 4.2 Détection automatique des problèmes N+1 ==== 
 + 
 +<WRAP round bloc important> 
 +**Objectif :** Détecter automatiquement les problèmes de performance sans analyse manuelle des logs 
 +</WRAP> 
 + 
 +=== Configuration === 
 + 
 +<sxh bash;gutter:false> 
 +# application.properties - Ajout pour Hypersistence 
 + 
 +# Détection des problèmes N+1 
 +logging.level.io.hypersistence.utils=DEBUG 
 + 
 +# Limites d'alerte (optionnel) 
 +hypersistence.query.fail.on.pagination.over.collection.fetch=false 
 +</sxh> 
 + 
 +=== Utilisation du QueryStackTraceLogger === 
 + 
 +<sxh java;gutter:false> 
 +// Configuration globale (classe @Configuration) 
 +@Configuration 
 +public class HypersistenceConfiguration { 
 +     
 +    @Bean 
 +    public QueryStackTraceLogger queryStackTraceLogger() { 
 +        return new QueryStackTraceLogger(); 
 +    } 
 +     
 +    @EventListener 
 +    public void onApplicationEvent(ApplicationReadyEvent event) { 
 +        // Active la détection des problèmes N+1 
 +        QueryStackTraceLogger.INSTANCE.setThreshold(10); // Alerte si > 10 requêtes 
 +    } 
 +
 +</sxh> 
 + 
 +**Exercice :**  
 +  * Activer le logger sur l'endpoint ''/users/{id}/orders'' 
 +  * Observer les alertes automatiques 
 +  * Corriger les problèmes détectés 
 + 
 +==== 4.3 Types JSON natifs ====
  
 <WRAP round bloc todo> <WRAP round bloc todo>
-=== Priorités (4h) ===+**Cas d'usage :** Stocker des métadonnées flexibles sur les produits 
 +</WRAP>
  
-**Must have :** +=== Exemple Attributs dynamiques produit ===
-  * ✅ Associations Order/OrderItem/User complètes avec tests +
-  * ✅ Résolution problème N+1 sur au moins 2 endpoints +
-  * ✅ Implémentation héritage produits (1 stratégie au choix) +
-  * ✅ Tests d'intégration validant les performances+
  
-**Nice to have :** +<sxh java;gutter:false> 
-  * Comparaison des 3 stratégies d'héritage +@Entity 
-  * DTO Projections avec MapStruct +@Table(name = "products"
-  * Benchmark avant/après optimisations +public class Product { 
-  * Documentation des choix architecturaux+    // ... attributs existants 
 +     
 +    @Type(JsonType.class) 
 +    @Column(columnDefinition = "json"
 +    private Map<String, Object> attributes; 
 +     
 +    // Pour PhysicalProduct : {"weight": 2.5, "dimensions": "30x20x10"
 +    // Pour DigitalProduct : {"fileSize": "1.2GB", "format": "PDF"
 +
 +</sxh> 
 + 
 +=== Données exemple === 
 + 
 +<sxh json;gutter:false> 
 +
 +  "id": "550e8400-e29b-41d4-a716-446655440020", 
 +  "name": "iPhone 15 Pro", 
 +  "price": 1199.99, 
 +  "stock": 25, 
 +  "categoryId": "550e8400-e29b-41d4-a716-446655440010", 
 +  "attributes":
 +    "color": "Titanium Blue", 
 +    "storage": "256GB", 
 +    "warranty": "2 years" 
 +  } 
 +
 +</sxh> 
 + 
 +**Exercice :** 
 +  * Ajouter le champ ''attributes'' à ''Product'
 +  * Créer un endpoint ''GET /products/{id}/attributes'' 
 +  * Filtrer les produits par attribut : ''GET /products?attr.color=Blue'' 
 + 
 +==== 4.4 Optimisation des identifiants avec Tsid ==== 
 + 
 +<WRAP round bloc info> 
 +**Tsid (Time-Sorted Identifiers)** : 
 +  * Alternative performante aux UUID 
 +  * Triables chronologiquement 
 +  * Plus compacts (Long au lieu de UUID) 
 +  * Meilleure performance en base
 </WRAP> </WRAP>
  
-===== Critères d'évaluation =====+=== Comparaison UUID vs Tsid ===
  
-^ Critère ^ Points ^ +<sxh java;gutter:false> 
-| Associations correctement mappées | 25% | +// Avant (UUID) 
-| Résolution problèmes N+1 | 30% | +@Id 
-| Implémentation héritage | 25% | +@GeneratedValue(strategy = GenerationType.UUID) 
-| Tests et qualité code | 20% |+private UUID id;
  
-===== Configuration supplémentaire =====+// Après (Tsid) - Pour nouvelles entités 
 +@Id 
 +@TsidGenerator 
 +private Long id; 
 +</sxh> 
 + 
 +**Exercice optionnel :** 
 +  * Créer une nouvelle entité ''Review'' avec Tsid 
 +  * Comparer les performances d'insertion (benchmark) 
 + 
 +<html><div class="imageB"></html> 
 +<uml> 
 +@startuml Review Domain Model 
 + 
 +class Review { 
 +  - id : Long 
 +  - rating : Integer 
 +  - title : String 
 +  - comment : String 
 +  - verified : Boolean 
 +  - helpfulCount : Integer 
 +  - createdAt : LocalDateTime 
 +  - updatedAt : LocalDateTime 
 +
 + 
 +class Product { 
 +  - id : UUID 
 +  - name : String 
 +  - price : BigDecimal 
 +  - stock : Integer 
 +
 + 
 +class User { 
 +  - id : UUID 
 +  - username : String 
 +  - email : String 
 +
 + 
 +Product "1" -- "0..*" Review : product 
 +User "1" -- "0..*" Review : author 
 + 
 +note right of Review 
 +  Contraintes métier : 
 +  • rating ∈ [1..5] 
 +  • 1 review max par (user, product) 
 +  • verified = true si achat confirmé 
 +  • helpfulCount >= 0 
 +   
 +  Tsid Generator pour l'id 
 +  (performance + tri chronologique) 
 +end note 
 + 
 +@enduml 
 + 
 + 
 + 
 +</uml> 
 +<html></div></html> 
 + 
 +==== 4.5 Monitoring des requêtes en temps réel ==== 
 + 
 +=== DataSourceProxyBeanPostProcessor === 
 + 
 +<sxh java;gutter:false> 
 +@Configuration 
 +public class DataSourceProxyConfiguration { 
 +     
 +    @Bean 
 +    public DataSourceProxyBeanPostProcessor dataSourceProxyBeanPostProcessor() { 
 +        return new DataSourceProxyBeanPostProcessor() { 
 +            @Override 
 +            protected DataSourceProxy createDataSourceProxy(DataSource dataSource) { 
 +                return new DataSourceProxy(dataSource, new QueryCountHolder()); 
 +            } 
 +        }; 
 +    } 
 +
 +</sxh> 
 + 
 +**Exercice :** 
 +  * Mettre en place le monitoring 
 +  * Créer un test d'intégration qui vérifie le nombre exact de requêtes 
 +  * Exemple : ''assertQueryCount(3)'' après un appel API 
 + 
 +==== 4.6 Exercice intégratif ==== 
 + 
 +<WRAP round bloc todo> 
 +**Mission :** Améliorer l'endpoint recommendations 
 + 
 +<sxh;gutter:false> 
 +GET /users/{id}/recommendations 
 +</sxh> 
 + 
 +**Avec Hypersistence :** 
 +  * Détecter automatiquement les problèmes N+1 
 +  * Limiter à 5 requêtes maximum (assertion en test) 
 +  * Stocker les préférences utilisateur en JSON 
 +  * Logger les performances de la recommandation 
 + 
 +**Structure JSON recommandée :** 
 +<sxh json;gutter:false> 
 +// User.preferences (JSON) 
 +
 +  "priceRange": {"min": 50, "max": 500}, 
 +  "brands": ["Apple", "Samsung"], 
 +  "excludeCategories": ["550e8400-..."
 +
 +</sxh> 
 +</WRAP> 
 + 
 +===== Configuration complète =====
  
-<sxh ini;gutter:false> +<sxh bash;gutter:false> 
-Voici la configuration en application.properties : +application.properties - Configuration complète Séance 2
-# Application properties - Séance 2+
  
 # H2 Database # H2 Database
Ligne 164: Ligne 375:
 spring.datasource.password= spring.datasource.password=
  
-# H2 Console (optionnel, pour debug)+# H2 Console
 spring.h2.console.enabled=true spring.h2.console.enabled=true
 spring.h2.console.path=/h2-console spring.h2.console.path=/h2-console
Ligne 175: Ligne 386:
 spring.jpa.properties.hibernate.generate_statistics=true spring.jpa.properties.hibernate.generate_statistics=true
  
-# Logging SQL et statistiques Hibernate+# Logging SQL et statistiques
 logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.SQL=DEBUG
 logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
 logging.level.org.hibernate.stat=DEBUG logging.level.org.hibernate.stat=DEBUG
-logging.level.org.hibernate.engine.internal.StatisticalLoggingSessionEventListener=WARN 
- 
-# Pour voir les paramètres des requêtes (optionnel mais utile) 
 logging.level.org.hibernate.orm.jdbc.bind=TRACE logging.level.org.hibernate.orm.jdbc.bind=TRACE
 +
 +# Hypersistence Utils
 +logging.level.io.hypersistence.utils=DEBUG
 </sxh> </sxh>
 +
 +===== Livrables attendus =====
 +
 +<WRAP round bloc todo>
 +=== Priorités (4h) ===
 +
 +**Must have :**
 +  * ✅ Associations Order/OrderItem/User complètes avec tests
 +  * ✅ Résolution problème N+1 sur au moins 2 endpoints
 +  * ✅ Implémentation héritage produits (1 stratégie au choix)
 +  * ✅ **Hypersistence : détection automatique N+1 activée**
 +  * ✅ Tests d'intégration validant les performances
 +
 +**Nice to have :**
 +  * Comparaison des 3 stratégies d'héritage
 +  * **Type JSON pour attributs dynamiques produits**
 +  * **Tsid sur une nouvelle entité (Review, Wishlist...)**
 +  * Benchmark avant/après optimisations avec query count assertions
 +  * Documentation des choix architecturaux
 +</WRAP>
  
 ===== Ressources ===== ===== Ressources =====
  
   * [[https://vladmihalcea.com/tutorials/hibernate/|Hibernate Performance Best Practices]]   * [[https://vladmihalcea.com/tutorials/hibernate/|Hibernate Performance Best Practices]]
 +  * [[https://github.com/vladmihalcea/hypersistence-utils|Hypersistence Utils GitHub]]
 +  * [[https://hypersistence.io/|Documentation officielle Hypersistence]]
   * [[https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods|Spring Data JPA Query Methods]]   * [[https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods|Spring Data JPA Query Methods]]
 +
  
 <WRAP round bloc info> <WRAP round bloc info>
  • eadl/bloc3/dev_av/td2.1759873240.txt.gz
  • Dernière modification : il y a 14 heures
  • de jcheron