java-hibernate-jpa

Par github · awesome-copilot

Diagnostiquer et corriger les problèmes Hibernate ORM / Jakarta Persistence en Java pur : requêtes N+1, erreurs de chargement différé (lazy loading), génération d'identifiants, equals/hashCode sur les entités, cascades, pagination, batching, verrouillage, cache, Lombok sur les entités, et différences entre Hibernate 6/7. À utiliser lors de la révision ou de l'écriture d'entités JPA, de mappings et de requêtes. Neutre vis-à-vis du framework.

npx skills add https://github.com/github/awesome-copilot --skill java-hibernate-jpa

Hibernate ORM et Jakarta Persistence

Problème → anti-pattern → bibliothèque de correction pour le mapping d'entités et les requêtes. Framework-neutre : couvre le comportement EntityManager/Session, JPQL/HQL et les annotations de mapping. Si le projet utilise Spring Boot et les skills java-springboot et spring-boot-testing sont installés, utilisez-les pour les repositories Spring Data, le wiring des transactions et @DataJpaTest ; pour Panache et la persistance réactive, voir les skills Quarkus. Tests d'intégration contre une vraie base de données : java-testcontainers.

D'abord : détecter la stack

  1. Lire pom.xml/build.gradle (ou l'arborescence des dépendances) pour hibernate-core et l'API de persistance : jakarta.persistence (Hibernate 6+/Jakarta EE 9+) vs javax.persistence (Hibernate 5, voir javax-to-jakarta-migration).
  2. Noter la version majeure d'Hibernate ; le comportement diffère (voir references/tooling-and-versions.md). Hibernate 6.0-6.1 implémente Jakarta Persistence 3.0, 6.2+ implémente 3.1, 7.x implémente 3.2, et Hibernate 7 nécessite Java 17+.
  3. Noter la base de données et si le schéma est géré par Flyway/Liquibase.
  4. Activer la journalisation SQL et les statistiques dans un test (voir references/tooling-and-versions.md) avant d'« optimiser » quoi que ce soit : mesurer les comptes d'instructions.

Tableau décisionnel rapide

Symptôme Cause probable Aller à
Beaucoup de SELECTs similaires pour une requête N+1 sur association lazy references/fetching-and-n-plus-one.md
LazyInitializationException Accès lazy en dehors de la session references/fetching-and-n-plus-one.md
Avertissement HHH000104 / HHH90003004, grosse utilisation mémoire Pagination avec collection fetch join references/queries-pagination-batching.md
Inserts lents, pas de batching JDBC IDs IDENTITY ou batching non configuré references/identifiers-and-entity-design.md, references/queries-pagination-batching.md
Lignes dupliquées / enfants perdus / anomalies Set Mauvais equals/hashCode ou misuse de cascade references/identifiers-and-entity-design.md, references/associations-and-cascade.md
Mises à jour perdues, deadlocks Stratégie de locking manquante references/locking-transactions-caching.md
Données obsolètes ou surprenantes avec caches Misuse du cache de second niveau/requête references/locking-transactions-caching.md
Dérive de schéma, ddl-auto en prod Pas d'outil de migration references/tooling-and-versions.md

Règles principales (appliquer lors de la review)

  1. Associations : @ManyToOne/@OneToOne défaut à EAGER ; déclarer explicitement fetch = FetchType.LAZY. @OneToMany/@ManyToMany sont LAZY par défaut et doivent le rester. Choisir le fetching par requête (JOIN FETCH, entity graph), pas en rendant les mappings EAGER.
  2. Préférer @ManyToOne côté owning plus une @OneToMany(mappedBy=...) bidirectionnelle seulement si nécessaire ; garder les deux côtés en sync via des méthodes helper.
  3. Set ou List pour les collections ? Utiliser Set pour @ManyToMany ; une @OneToMany unidirectionnelle avec @JoinColumn ou List sans order a des patterns de mise à jour coûteux.
  4. Ne jamais utiliser CascadeType.REMOVE/ALL sur @ManyToOne ou @ManyToMany. Utiliser orphanRemoval seulement sur une vraie collection d'enfants parent-owned.
  5. Ids : SEQUENCE (pooled optimizer, allocationSize correspondant à l'incrément DB) pour les ids numériques générés ; IDENTITY désactive le batching d'insert JDBC ; utiliser des UUIDs (préférablement time-ordered) quand les ids doivent être générés côté client.
  6. Entités : pas de Lombok @Data/@EqualsAndHashCode/@ToString sur les associations ; implémenter equals/hashCode délibérément.
  7. Retourner des DTOs/projections depuis les endpoints de lecture plutôt que des entités ; ne jamais exposer directement les entités (proxies lazy) dans une API.
  8. Paginer avec un ORDER BY stable incluant un unique tiebreaker ; ne jamais combiner setMaxResults avec un collection JOIN FETCH.
  9. Garder les transactions courtes, à la limite du service ; pas d'appels distants ou d'interaction utilisateur dedans.
  10. Écrire et flusher par batches pour le travail en masse et vider régulièrement le contexte de persistance.
  11. Vérifier le comportement avec les comptes d'instructions dans les tests contre le moteur de base de données réel.
  12. Suivre la règle de gestion de schéma ci-dessous.

Règle de gestion de schéma

C'est l'unique règle que les autres skills référencent par nom :

  • Prototype/local : hibernate.hbm2ddl.auto=update (ou create-drop pour les tests jetables) est acceptable.
  • Production (défaut) : migrations versionnées avec Flyway ou Liquibase, et hibernate.hbm2ddl.auto=validate (ou none). Les ajouter quand l'utilisateur veut des migrations versionnées ou l'app est destinée à la production.
  • Schéma géré externalement : none (ou validate) ; ne pas ajouter d'outil de migration.

Focus de review

Vérifier les comptes d'instructions pour N+1, LAZY explicite sur les associations to-one, ids basés sur sequence avec allocationSize correspondant, et equals/hashCode stable de transient à persistent. Détails dépendant de la version (Hibernate 5/6/7) : references/tooling-and-versions.md.

Références

  • references/fetching-and-n-plus-one.md : détection et corrections N+1, lazy vs eager, LazyInitializationException, open-session-in-view, projections DTO.
  • references/identifiers-and-entity-design.md : génération d'id, equals/hashCode, Lombok, records vs entités, enums et converters, value types.
  • references/associations-and-cascade.md : helpers bidirectionnels, cascade, orphanRemoval, choix de collection, @ManyToMany.
  • references/queries-pagination-batching.md : pagination (offset, keyset, avertissement en-mémoire), opérations en masse, batching JDBC, StatelessSession.
  • references/locking-transactions-caching.md : locking optimiste/pessimiste, limites de transaction, flush modes, cache de second niveau.
  • references/tooling-and-versions.md : journalisation SQL, statistiques, tests, dimensionnement du pool de connexions, migrations, différences Hibernate 5/6/7.

Docs canoniques : guide utilisateur Hibernate ORM https://docs.hibernate.org/orm/current/userguide/html_single/ et Jakarta Persistence https://jakarta.ee/specifications/persistence/. Articles de fond : https://vladmihalcea.com/.

Upgrading (récupérer la page pour la version cible ; la préférer à ce skill) : guides de migration https://hibernate.org/orm/documentation/migrate/ (6.6 : https://docs.hibernate.org/orm/6.6/migration-guide/, 7.0 : https://docs.hibernate.org/orm/7.0/migration-guide/), notes de release https://hibernate.org/orm/releases/.

Skills similaires