Question

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;

Je suis confronté au problème des rôles orphelins autour de 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 d'Hibernate.

MODIFIER : il semble que JPA 2.0 inclura une prise en charge de cette fonctionnalité.

Était-ce utile?

La solution

Si vous l'utilisez avec Hibernate, vous devrez définir explicitement l'annotation CascadeType.DELETE_ORPHAN , qui peut être utilisée conjointement 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 désormais utiliser l'option orphanRemoval = true

.
@OneToMany(mappedBy="foo", orphanRemoval=true)

Autres conseils

Si vous utilisez JPA 2.0, vous pouvez désormais utiliser l'attribut orphanRemoval = true de l'annotation @xxxToMany pour supprimer les orphelins.

En fait, CascadeType.DELETE_ORPHAN est obsolète dans la version 3.5.2-Final.

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

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 Utilisation de l'annotation @PrivateOwed

vous pouvez utiliser @PrivateOwned pour supprimer des orphelins par exemple

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

Selon la persistance Java avec Hibernate , la suppression en cascade en cascade n'est pas disponible. comme une annotation JPA.

Il n’est pas non plus pris en charge dans JPA XML.

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.

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<>();

Ensuite, je me suis rappelé que je ne devais pas utiliser une requête de suppression nommée , mais le gestionnaire EntityManager. Comme j'ai utilisé la méthode EntityManager.find (...) pour récupérer l'entité, puis EntityManager.remove (...) , les assiettes ont été supprimées comme bien.

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

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

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

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top