web-dev-qa-db-fra.com

JPA CascadeType.ALL ne supprime pas les orphelins

Je ne parviens pas à supprimer des nœuds orphelins à l'aide de JPA avec le mappage suivant

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;

J'ai des problèmes avec les rôles orphelins qui traînent dans la base de données.

Je peux utiliser l'annotation org.hibernate.annotations.Cascade Balise spécifique à Hibernate, mais je ne souhaite évidemment pas lier ma solution à une implémentation Hibernate.

EDIT : Il semble que JPA 2.0 inclura le support pour cela.

130
Paul Whelan

Si vous l’utilisez avec Hibernate, vous devrez définir explicitement l’annotation CascadeType.DELETE_Orphan, qui peut être utilisé avec JPA CascadeType.ALL.

Si vous n'envisagez pas d'utiliser Hibernate, vous devez d'abord explicitement supprimer les éléments enfants, puis supprimer l'enregistrement principal pour éviter tout enregistrement orphelin.

séquence d'exécution

  1. récupère la ligne principale à supprimer
  2. récupérer des éléments enfants
  3. supprimer tous les éléments enfants
  4. supprimer la ligne principale
  5. fermer la session

Avec JPA 2.0, vous pouvez maintenant utiliser l'option orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true)
157
Varun Mehta

Si vous utilisez JPA 2.0, vous pouvez maintenant utiliser le orphanRemoval=true _ attribut du @xxxToMany annotation pour supprimer les orphelins.

Réellement, CascadeType.DELETE_Orphan est obsolète dans 3.5.2-Final.

112
Kango_V
╔═════════════╦═════════════════════╦═════════════════════╗
║   Action    ║  orphanRemoval=true ║   CascadeType.ALL   ║
╠═════════════╬═════════════════════╬═════════════════════╣
║   delete    ║     deletes parent  ║    deletes parent   ║
║   parent    ║     and orphans     ║    and orphans      ║
╠═════════════╬═════════════════════╬═════════════════════╣
║   change    ║                     ║                     ║
║  children   ║   deletes orphans   ║      nothing        ║
║    list     ║                     ║                     ║
╚═════════════╩═════════════════════╩═════════════════════╝
43
Sergii Shevchyk

Si vous utilisez JPA avec EclipseLink, vous devez définir l'annotation @ PrivateOwned .

Documentation: Eclipse Wiki - Utilisation des extensions JPA d'EclipseLink - Chapitre 1.4 Comment utiliser l'annotation @PrivateOwned

12

vous pouvez utiliser @PrivateOwned pour supprimer des orphelins, par exemple

@OneToMany(mappedBy = "masterData", cascade = {
        CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;
7
reshma

Je viens de trouver cette solution mais dans mon cas cela ne fonctionne pas:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = true n'a aucun effet.

4
Valéry Stroeder

Selon Java Persistence with Hibernate , en cascade orphan delete n'est pas disponible en tant qu'annotation JPA.

Il n'est également pas pris en charge dans JPA XML.

4
toolkit

J'ai eu le même problème et je me suis demandé pourquoi cette condition ci-dessous ne supprimait pas les orphelins. La liste des plats n'a pas été supprimée dans Hibernate (5.0.3.Final) lorsque j'ai exécuté une requête de suppression nommée:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();

Puis je me suis rappelé que je ne doit pas utiliser une requête de suppression nommée, mais le EntityManager. Comme j'ai utilisé la méthode EntityManager.find(...) pour récupérer l'entité puis EntityManager.remove(...) pour la supprimer, les plats ont également été supprimés.

2
Bevor

Juste @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

Remove targetEntity = MyClass.class, cela fonctionne très bien.

2
Kohan95

Pour les enregistrements, dans OpenJPA avant JPA2, il s’agissait de @ElementDependant.

1
Simone Gianni

J'utilisais un mappage un à un, mais l'enfant n'était pas supprimé. JPA donnait une violation de clé étrangère.

Après avoir utilisé orphanRemoval = true, le problème a été résolu.

0
vipin chauhan