Spring Data JPA & Hibernate

Entités, relations, transactions, performance, locking, cascade, mapping professionnel : maîtrisez Spring Data JPA & Hibernate comme en entreprise.

Introduction

Spring Data JPA permet de manipuler des données de manière simple, tout en s’appuyant sur Hibernate, le moteur ORM le plus utilisé dans l’écosystème Java. Pour produire des applications fiables et performantes, il est essentiel de comprendre les mécanismes internes, la gestion des transactions et l’impact des relations.

Ce chapitre vous donne une maîtrise avancée de Spring Data JPA : mapping, relations, cascade, transactions, performance, pagination, verrouillages et bonnes pratiques.

Lexique essentiel

Entity
Objet métier persistant géré par Hibernate.
Repository
Interface Spring Data pour manipuler les entités.
Lazy Loading
Chargement à la demande pour éviter les surcoûts.
Transaction
Contexte d’exécution garantissant la cohérence des données.
Locking
Mécanismes de concurrence : pessimistic / optimistic.
Cascade
Propagation des opérations (persist, remove, merge…).

1. Créer une entité propre et professionnelle


@Entity
@Table(name = "orders")
public class Order {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String customerId;

    @Enumerated(EnumType.STRING)
    private OrderStatus status;

    private BigDecimal total;

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<OrderItem> items = new ArrayList<>();
}
    

Bonnes pratiques : toujours utiliser EnumType.STRING, éviter les relations bidirectionnelles sauf si nécessaire, et préférer orphanRemoval pour un modèle propre.

Repository minimaliste


public interface OrderRepository extends JpaRepository<Order, Long> {

    List<Order> findByCustomerId(String customerId);

    @Query("select o from Order o where o.status = :status")
    List<Order> findByStatus(@Param("status") OrderStatus status);
}
    

Service transactionnel


@Service
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository repository;

    @Transactional
    public Order create(Order order) {
        return repository.save(order);
    }

    @Transactional(readOnly = true)
    public List<Order> listByCustomer(String id) {
        return repository.findByCustomerId(id);
    }
}
    

Règle : toujours annoter les services avec @Transactional. Ne jamais mettre @Transactional dans le controller.

Lazy vs Eager : les choix qui tuent les perfs

Par défaut, les relations @OneToMany et @ManyToOne doivent rester en LAZY. L’utilisation de EAGER entraîne un chargement massif imprévisible (anti-pattern fréquent chez les débutants).

DTO d’exposition propre


public record OrderResponse(
    Long id,
    BigDecimal total,
    String status
) {}
    
Bonnes pratiques :
  • Jamais d’entité dans les controllers.
  • DTO → mapper → entité → service → repository.
  • Toujours lire en mode LAZY, charger explicitement quand nécessaire.
  • Utiliser des transactions lisibles, cohérentes et centrées métier.

2. Performance & optimisation Hibernate

Pagination obligatoire sur les grandes collections


Page<Order> orders = repository.findAll(PageRequest.of(page, size));
    

Projections pour réduire l’overfetching


public interface OrderSummary {
    Long getId();
    BigDecimal getTotal();
}
    

Les projections réduisent drastiquement la quantité de données lues.

Optimistic Locking


@Version
private Long version;
    

Empêche les mises à jour concurrentes silencieuses.

Métriques indispensables

  • Nombre de requêtes SQL
  • Temps moyen d’une transaction
  • Pourcentage de lazy loading déclenché dans le controller (❌)

Quiz : Spring Data JPA & Hibernate

  • Q1. Où doit se trouver l’annotation @Transactional ?
    • A. Dans le controller
    • B. Dans le service ✔
    • C. Dans l’entité
  • Q2. Quelle stratégie de fetch privilégier ?
    • A. EAGER
    • B. LAZY ✔
    • C. Aucune

Exercice d’application

Implémentez un module complet « Produits » avec :
— Entité propre
— Repository
— Service transactionnel
— Relations OneToMany pour les catégories
— Pagination
— Projection optimisée
— DTO de sortie

Résumé

Spring Data JPA & Hibernate offrent un cadre puissant pour manipuler des données, mais exigent une compréhension fine des relations, transactions, performances et patterns. Une pratique rigoureuse garantit un code propre, stable et scalable.

Review My Order

0

Subtotal