JPA: suppression unidirectionnelle plusieurs-à-un et en cascade

Disons que j’ai une relation unidirectionnelle @ManyToOne comme celle-ci:

 @Entity public class Parent implements Serializable { @Id @GeneratedValue private long id; } @Entity public class Child implements Serializable { @Id @GeneratedValue private long id; @ManyToOne @JoinColumn private Parent parent; } 

Si j’ai un parent P et des enfants C 1 … C n faisant référence à P, y a-t-il une manière propre et jolie dans JPA de supprimer automatiquement les enfants C 1 … C n lorsque P est supprimé (ie entityManager.remove(P) )?

Ce que je cherche, c’est une fonctionnalité similaire à ON DELETE CASCADE en SQL.

Les relations dans JPA sont toujours unidirectionnelles, sauf si vous associez le parent avec l’enfant dans les deux sens. Les opérations REMOVE en cascade du parent à l’enfant nécessitent une relation entre le parent et l’enfant (et pas seulement l’inverse).

Vous devrez donc faire ceci:

  • Soit, changez la relation unidirectionnelle @ManyToOne avec un @ManyToOne , ou un @OneToMany unidirectionnel. Vous pouvez ensuite mettre en cascade les opérations REMOVE pour que EntityManager.remove supprime le parent et les enfants. Vous pouvez également spécifier orphanRemoval comme true pour supprimer tous les enfants orphelins lorsque l’entité enfant de la collection parent est définie sur null, c’est-à-dire supprimer l’enfant lorsqu’il n’est pas présent dans la collection d’un parent.
  • Ou, spécifiez la contrainte de clé étrangère dans la table enfant comme ON DELETE CASCADE . Vous devrez appeler EntityManager.clear() après avoir appelé EntityManager.remove(parent) car le contexte de persistance doit être actualisé – les entités enfants ne sont pas supposées exister dans le contexte de persistance après leur suppression dans la firebase database.

Si vous utilisez Hibernate comme fournisseur JPA, vous pouvez utiliser l’annotation @OnDelete. Cette annotation appenda à la relation le déclencheur ON DELETE CASCADE , qui délègue la suppression des enfants à la firebase database.

Exemple:

 public class Parent { @Id private long id; } public class Child { @Id private long id; @ManyToOne @OnDelete(action = OnDeleteAction.CASCADE) private Parent parent; } 

Avec cette solution, une relation unidirectionnelle entre l’enfant et le parent suffit pour supprimer automatiquement tous les enfants. Cette solution n’a pas besoin d’écoute, etc. Une requête comme DELETE FROM Parent WHERE id = 1 va également supprimer les enfants.

Créez une relation bidirectionnelle, comme ceci:

 @Entity public class Parent implements Serializable { @Id @GeneratedValue private long id; @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE) private Set children; } 

@Cascade (org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

L’annotation donnée a fonctionné pour moi. Peut essayer

Par exemple :-

  public class Parent{ @Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="cct_id") private Integer cct_id; @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) private List childs; } public class Child{ @ManyToOne(fetch=FetchType.EAGER) @JoinColumn(name="cct_id") private Parent parent; }