Le cycle de vie des entités JPA

Java
I211
Lecture
JPA
Réaction aux évènements liés au cycle de vie des entités JPA.
Auteur
Affiliations

Université de Toulon

LIS UMR CNRS 7020

Date de publication

2025-01-30

Source
Branch
  • develop (c88a48e)
  • 2024/03/08 11:41:10
Java
  • OpenJDK Temurin-21.0.5+11
  • Apache Maven 3.9.9
Docker
  • Client: 27.3.1 - buildx v0.18.0 - compose v2.30.3
  • Server: 27.3.1

1 Cycle de vie d’une entité

Le cycle de vie d’une entité JPA définit les différents états possibles d’une instance (New, Managed, Detached, Removed) et les transitions entre ces états via les opérations de l’EntityManager (persist(), merge(), remove(), detach()), permettant ainsi le suivi et la gestion de la synchronisation entre les objets Java en mémoire et leur représentation en base de données.

stateDiagram-v2
    [*] --> New: new Entity()
    New --> Managed: persist()
    Managed --> Detached: detach()/close()
    Managed --> Removed: remove()
    Detached --> Managed: merge()
    Managed --> [*]: clear()
    Removed --> [*]

2 Etats d’une entité

  • New (Transient)
    • Nouvelle instance Java
    • Inconnue de JPA
    • Pas d’identifiant assigné
  • Managed (Persistent)
    • Gérée par EntityManager
    • Synchronisée avec la BD
    • Modifications automatiquement persistées
  • Detached
    • Plus gérée par EntityManager
    • Modifications non suivies
    • Nécessite merge() pour synchroniser
  • Removed
    • Marquée pour suppression
    • Sera supprimée en BD

3 Callbacks du cycle de vie

Comme le cycle de vie des entités géré par JPA, des annotations spécifiques sont proposées pour exécuter des méthodes de Callback d’une entités à des moments spécifiques :

  • Persistence
    • @PrePersist: avant persist()
    • @PostPersist: après persist()
  • Update
    • @PreUpdate: avant modification
    • @PostUpdate: après modification
  • Remove
    • @PreRemove: avant suppression
    • @PostRemove: après suppression
  • Load
    • @PostLoad: après chargement

4 Callbacks sur l’entité

  • Annotations sur méthodes de l’entité
  • Exécutées automatiquement lors des transitions
@Entity
public class Customer {
    @PrePersist
    void onCreate() {
        this.createdAt = LocalDateTime.now();
    }
}

4.1 Exemple : Listener

Définir un ou des Listener : des classes dédiées à la réaction aux évènements du cycle de vie d’une entités.

@Slf4j
public class EntityMonitorListener {
    @PrePersist
    @PreUpdate
    @PreRemove
    private void beforeAnyUpdate(Object entity) {
        log.info("-->about to change in DB: " + entity);
    }

    @PostPersist
    @PostUpdate
    @PostRemove
    private void afterAnyUpdate(Object entity) {
        log.info("--> changed in DB" + entity);
    }

    @PostLoad
    private void afterLoad(Object entity) {
        log.info("--> loaded from DB: " + entity);
    }
}

4.2 Exemple : Entité avec Listener

Les associer à une ou plusieurs entités (@EntityListeners).

@Entity
@Table(name = "CUSTOMER_BIS")
@EntityListeners(EntityMonitorListener.class)
@Getter
@Setter
@ToString
@RequiredArgsConstructor(staticName = "of")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Slf4j
public class CustomerWithListener {
    @Id
    @GeneratedValue
    private long id;

    @NonNull
    private String name;
}

Réutilisation