-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path05_java_jpa_L_lifecycle.qmd
More file actions
160 lines (132 loc) · 5.08 KB
/
Copy path05_java_jpa_L_lifecycle.qmd
File metadata and controls
160 lines (132 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
---
title: Le cycle de vie des entités JPA
description: Réaction aux évènements liés au cycle de vie des entités JPA.
categories:
- Java
- I211
- Lecture
- JPA
provide_notes: true
provide_slides: true
jupyter: java
---
{{< include ./_init.qmd >}}
## 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.
```{mermaid}
stateDiagram-v2
[*] --> New: new Entity()
New --> Managed: persist()
Managed --> Detached: detach()/close()
Managed --> Removed: remove()
Detached --> Managed: merge()
Managed --> [*]: clear()
Removed --> [*]
```
## 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
## 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
## Callbacks sur l'entité
- Annotations sur méthodes de l'entité
- Exécutées automatiquement lors des transitions
```java
@Entity
public class Customer {
@PrePersist
void onCreate() {
this.createdAt = LocalDateTime.now();
}
}
```
```{java}
//| output: false
//| echo: false
//| vscode: {languageId: java}
import fr.univtln.bruno.demos.jpa.hello.samples.ex_associations.ex_onetomany_a.*;
EntityManagerFactory emf = DatabaseManager.getEntityManagerFactory();
final Logger log = LoggerFactory.getLogger("notebook");
```
```{java}
//| vscode: {languageId: java}
import fr.univtln.bruno.demos.jpa.hello.samples.ex_hook.Customer;
try (EntityManager entityManager = emf.createEntityManager()) {
entityManager.getTransaction().begin();
Customer customer = Customer.of("Peter");
log.info(customer.toString());
entityManager.persist(customer);
customer.setName("Pierre");
entityManager.getTransaction().commit();
try (EntityManager anotherEM = emf.createEntityManager()) {
log.info("FOUND " + anotherEM.find(Customer.class, 1L));
}
entityManager.getTransaction().begin();
entityManager.remove(customer);
entityManager.getTransaction().commit();
}
```
### 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.
```{java}
//| output: true
//| echo: false
//| vscode: {languageId: java}
// PRINT CLASS
String script="/home/jovyan/work/src/github/ebpro/sample-hellojpa/src/main/java/fr/univtln/bruno/demos/jpa/hello/samples/ex_hook/EntityMonitorListener.java";
IJava.getKernelInstance().getMagics().applyCellMagic("javasrcClassByName",List.of("EntityMonitorListener"),script);
return null;
```
### Exemple : Entité avec Listener
Les associer à une ou plusieurs entités (`@EntityListeners`).
```{java}
//| output: true
//| echo: false
//| vscode: {languageId: java}
// PRINT CLASS
String script="/home/jovyan/work/src/github/ebpro/sample-hellojpa/src/main/java/fr/univtln/bruno/demos/jpa/hello/samples/ex_hook/CustomerWithListener.java";
IJava.getKernelInstance().getMagics().applyCellMagic("javasrcClassByName",List.of("CustomerWithListener"),script);
return null;
```
```{java}
//| vscode: {languageId: java}
import fr.univtln.bruno.demos.jpa.hello.samples.ex_hook.CustomerWithListener;
try (EntityManager entityManager = emf.createEntityManager()) {
entityManager.getTransaction().begin();
CustomerWithListener customer = CustomerWithListener.of("Peter");
log.info(customer.toString());
entityManager.persist(customer);
customer.setName("Pierre");
entityManager.getTransaction().commit();
try (EntityManager anotherEM = emf.createEntityManager()) {
log.info("FOUND " + anotherEM.find(CustomerWithListener.class, 1L));
}
entityManager.getTransaction().begin();
entityManager.remove(customer);
entityManager.getTransaction().commit();
}
```