Je suis un peu confus à propos de l’atsortingbut orphanRemoval
JPA 2.0.
Je pense que je peux voir que cela est nécessaire lorsque j’utilise les outils de génération de firebase database de mon fournisseur JPA pour créer la firebase database DDL sous-jacente pour avoir un ON DELETE CASCADE
sur la relation particulière.
Cependant, si la firebase database existe et qu’elle a déjà un ON DELETE CASCADE
sur la relation, est-ce que cela ne suffit pas pour procéder à la cascade de manière appropriée? Que fait l’ orphanRemoval
en plus?
À votre santé
orphanRemoval
n’a rien à voir avec ON DELETE CASCADE
.
orphanRemoval
est une chose entièrement spécifique à ORM . Il marque l’entité “enfant” à supprimer lorsqu’il n’est plus référencé par l’entité “parent”, par exemple lorsque vous supprimez l’entité enfant de la collection correspondante de l’entité parent.
ON DELETE CASCADE
est une chose spécifique à la firebase database , il supprime la ligne “child” dans la firebase database lorsque la ligne “parent” est supprimée.
Un exemple pris ici :
Lorsqu’un object entité Employee
est supprimé, l’opération de suppression est mise en cascade sur l’object entité Address
référencé. À cet égard, orphanRemoval=true
et cascade=CascadeType.REMOVE
sont identiques et si orphanRemoval=true
est spécifié, CascadeType.REMOVE
est redondant.
La différence entre les deux parameters réside dans la réponse à la déconnexion d’une relation. Par exemple, lorsque vous définissez le champ d’adresse sur null
ou sur un autre object Address
.
Si orphanRemoval=true
est spécifié, l’instance d’ Address
déconnectée est automatiquement supprimée. Ceci est utile pour nettoyer les objects dépendants (par exemple, Address
) qui ne devraient pas exister sans une référence provenant d’un object propriétaire (par exemple, Employee
).
Si seule cascade=CascadeType.REMOVE
est spécifiée, aucune action automatique n’est prise car la déconnexion d’une relation n’est pas une opération de suppression.
Pour éviter de perdre des références suite à la suppression d’orphelin, cette fonctionnalité ne doit être activée que pour les champs contenant des objects dépendants non partagés privés.
J’espère que cela le rend plus clair.
Au moment où vous supprimez une entité enfant de la collection, vous supprimez également cette entité enfant de la firebase database. orphanRemoval implique également que vous ne pouvez pas changer de parents; S’il y a un service qui a des employés, une fois que vous avez retiré cet employé pour le placer dans un autre département, vous aurez par inadvertance retiré cet employé de la firebase database à la sortie / validation (avant tout). Le moral est de définir orphanRemoval sur true tant que vous êtes certain que les enfants de ce parent ne migreront pas vers un autre parent au cours de leur existence. L’activation de orphanRemoval ajoute également automatiquement REMOVE à la liste en cascade.
Le mappage JPA équivalent pour le DDL ON DELETE CASCADE
est cascade=CascadeType.REMOVE
. La suppression orpheline signifie que les entités dépendantes sont supprimées lorsque la relation avec leur entité “parent” est détruite. Par exemple, si un enfant est supprimé d’une relation @OneToMany
sans le supprimer explicitement dans le gestionnaire d’entités.
La réponse de @GaryK est absolument géniale, j’ai passé une heure à chercher une explication orphanRemoval = true
vs CascadeType.REMOVE
et cela m’a aidé à comprendre.
En résumé: orphanRemoval = true
fonctionne comme CascadeType.REMOVE
UNIQUEMENT SI nous entityManager.delete(object)
object ( entityManager.delete(object)
) et que nous voulons également que les objects childs soient supprimés.
Dans une situation complètement différente, lorsque nous récupérons des données telles que List
et entityManager.remove(childs.get(0)
un enfant ( entityManager.remove(childs.get(0)
)), orphanRemoval=true
provoquera cette entité correspondant à childs.get(0)
sera supprimé de la firebase database.
La suppression des orphelins a le même effet que ON DELETE CASCADE dans le scénario suivant: – Disons que nous avons une relation simple entre plusieurs parties entre une entité étudiante et une entité guide, où de nombreux étudiants peuvent être mappés au même guide. relation de clé étrangère entre Student et Guide table telle que la table des étudiants a id_guide comme FK.
@Entity @Table(name = "student", catalog = "helloworld") public class Student implements java.io.Serializable { @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id") private Integer id; @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE}) @JoinColumn(name = "id_guide") private Guide guide;
// L’entité parent
@Entity @Table(name = "guide", catalog = "helloworld") public class Guide implements java.io.Serializable { /** * */ private static final long serialVersionUID = 9017118664546491038L; @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) private Integer id; @Column(name = "name", length = 45) private Ssortingng name; @Column(name = "salary", length = 45) private Ssortingng salary; @OneToMany(mappedBy = "guide", orphanRemoval=true) private Set students = new HashSet (0);
Dans ce scénario, la relation est telle que l’entité de l’étudiant est le propriétaire de la relation et, en tant que telle, nous avons besoin de sauvegarder l’entité de l’étudiant pour conserver le graphe d’object entier, par exemple
Guide guide = new Guide("John", "$1500"); Student s1 = new Student(guide, "Roy","ECE"); Student s2 = new Student(guide, "Nick", "ECE"); em.persist(s1); em.persist(s2);
Ici, nous cartographions le même guide avec deux objects étudiants différents et comme CASCADE.PERSIST est utilisé, le graphe d’object sera enregistré comme ci-dessous dans la table de firebase database (MySql dans mon cas).
Table STUDENT: –
1 Roy ECE 1
2 Nick ECE 1
1 John 1500 $
et maintenant si je veux supprimer l’un des étudiants, en utilisant
Student student1 = em.find(Student.class,1); em.remove(student1);
et lorsqu’un enregistrement d’étudiant est supprimé, l’enregistrement de guide correspondant doit également être supprimé, c’est-à-dire que l’atsortingbut CASCADE.REMOVE dans l’entité Étudiant entre dans l’image et ce qu’il fait: il supprime l’identificateur 1 ainsi que l’object guide correspondant (identifiant 1). Mais dans cet exemple, il y a un autre object étudiant qui est mappé sur le même enregistrement de guide et à moins d’utiliser l’ atsortingbut orphanRemoval = true dans l’entité Guide, le code de suppression ci-dessus ne fonctionnera pas.
La différence est:
– orphanRemoval = true: l’entité “Child” est supprimée lorsqu’elle n’est plus référencée (son parent ne peut pas être supprimé).
– CascadeType.REMOVE: l’entité “Child” n’est supprimée que lorsque son “Parent” est supprimé.