Transitions d'état des entités
JPA traduit les transitions d'état des entités en instructions SQL, comme INSERT, UPDATE ou DELETE.
Quand vous persist
une entité, vous planifiez l'instruction INSERT pour qu'elle soit exécutée lorsque l'entité EntityManager
est vidée, soit automatiquement, soit manuellement.
quand vous remove
une entité, vous planifiez l'instruction DELETE, qui sera exécutée lorsque le contexte de persistance sera purgé.
Transitions d'état des entités en cascade
Pour des raisons de commodité, JPA vous permet de propager les transitions d'état d'entité des entités mères aux entités filles.
Donc, si vous avez un parent Post
entité qui a un @OneToMany
association avec le PostComment
entité enfant :
Le site comments
dans la collection Post
est mise en correspondance comme suit :
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();
CascadeType.ALL
Le site cascade
indique au fournisseur JPA de transmettre la transition d'état de l'entité depuis le parent Post
entité à tous les PostComment
entités contenues dans le comments
collection.
Ainsi, si vous supprimez le Post
entité :
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
entityManager.remove(post);
Le fournisseur JPA va supprimer le PostComment
d'abord, et lorsque toutes les entités enfants sont supprimées, il supprime l'entité Post
également :
DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2
DELETE FROM post WHERE id = 1
Suppression des orphelins
Lorsque vous réglez le orphanRemoval
à l'attribut true
le fournisseur JPA va programmer un remove
lorsque l'entité enfant est retirée de la collection.
Donc, dans notre cas,
Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());
PostComment postComment = post.getComments().get(0);
assertEquals(1L, postComment.getId());
post.getComments().remove(postComment);
Le fournisseur JPA va supprimer l'adresse de l'utilisateur de l'application post_comment
depuis le PostComment
n'est plus référencée dans le comments
collection :
DELETE FROM post_comment WHERE id = 1
SUR LA SUPPRESSION EN CASCADE
Le site ON DELETE CASCADE
est défini au niveau du FK :
ALTER TABLE post_comment
ADD CONSTRAINT fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post
ON DELETE CASCADE;
Une fois que vous avez fait cela, si vous supprimez un post
rang :
DELETE FROM post WHERE id = 1
Tous les éléments associés post_comment
Les entités sont supprimées automatiquement par le moteur de la base de données. Cependant, cette opération peut s'avérer très dangereuse si vous supprimez une entité Root par erreur.
Conclusion
L'avantage de la JPA cascade
et orphanRemoval
est que vous pouvez également bénéficier du verrouillage optimiste pour éviter les mises à jour perdues.
Si vous utilisez le mécanisme de mise en cascade de JPA, vous n'avez pas besoin d'utiliser les fonctions de niveau DDL ON DELETE CASCADE
Cette opération peut s'avérer très dangereuse si vous supprimez une entité racine qui possède de nombreuses entités filles à plusieurs niveaux.