174 votes

OneToMany JPA ne pas suppression d’enfant

j'ai un problème avec un simple @OneToMany mappage entre un parent et un enfant entité. Tous fonctionne bien, seulement que l'enfant enregistrements ne sont pas supprimés lorsque je les supprime de la collection.

Le parent:

@Entity
public class Parent {
    @Id
    @Column(name = "ID")
    private Long id;

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent")
    private Set<Child> childs = new HashSet<Child>();

 ...
}

L'enfant:

@Entity
public class Child {
    @Id
    @Column(name = "ID")
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="PARENTID", nullable = false)
    private Parent parent;

  ...
}

Si j'ai maintenant supprimer l'enfant, de l'enfant Ensemble, il n'est pas supprimé de la base de données. J'ai essayé de détruire l'enfant.parent de référence, mais cela ne fonctionne pas non plus.

Les entités sont utilisés dans une application web, la suppression se produit dans le cadre d'une requête ajax. Je n'ai pas de liste de supprimé childs lorsque le bouton enregistrer est pressé, donc je ne peux pas les supprimer de façon implicite.

Les pointeurs? Merci d'avance pour votre temps

279voto

cletus Points 276888

JPA comportement est correct (ce qui signifie que par la spécification): les objets ne sont pas supprimés simplement parce que vous avez supprimé à partir d'un OneToMany collection. Il y a des extensions spécifiques au fournisseur qui le font, mais natif JPA ne répond pas.

C'est en partie parce que JPA n'est pas réellement savoir si elle devrait supprimer quelque chose retiré de la collection. Dans la modélisation d'objet, c'est la différence entre composition et agrégation*.

Dans la composition, l'enfant entité n'a pas d'existence sans la mère. Un exemple classique est entre la Maison et des chambres. Supprimer la Maison et les Chambres de trop.

L'agrégation est un looser type d'association et sont caractérisés par des Cours et des Étudiants. Supprimer le Cours et l'Étudiant existe encore (probablement dans d'autres Cours).

Si vous avez besoin d'utiliser des extensions spécifiques au fournisseur pour forcer ce comportement (si disponible) ou explicitement supprimer l'enfant ET de l'enlever de la mère de la collection.

Je suis au courant de:

81voto

Louis Jacomet Points 650

En plus de cletus réponse, JPA 2.0, finale depuis décembre 2010, introduit une orphanRemoval attribut @oneToManydes annotations. Pour plus de détails, voir cette entrée de blog.

À noter que depuis la spec est relativement nouvelle, pas tous JPA 1 fournisseur de finale de JPA 2 mise en œuvre. Par exemple, la veille prolongée 3.5.0-Bêta-2 version ne prend pas encore en charge cet attribut.

48voto

Vous pouvez essayer d’utiliser cela aussi :

``.

A fonctionné pour moi. ;-)

21voto

bert Points 3906

Merci pour vos deux réponses. Je réponds à moi-même pour afficher le code qui a résolu mon problème. Comme expliqué, il n’est pas possible de faire ce que je veux avec JPA, donc j’ai employé l’annotation hibernate.cascade, avec cela, le code correspondant dans la classe parente ressemble maintenant à ceci :

Je ne pouvais pas simple « ALL » utiliser comme cela serait ont supprimé le parent aussi bien.

Merci encore pour vos réponses.

4voto

Chandra Patni Points 9432

Cascade, dans le cadre de la suppression, signifie ici que les enfants sont supprimées si vous supprimez le parent. Pas l’association. Si vous utilisez Hibernate comme votre fournisseur d’App, vous pouvez le faire en utilisant hibernate cascade spécifique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X