2009-07-15 6 views
1

J'ai une entité JPA "Request", qui possède une liste de réponses (également des entités JPA). Voilà comment il est défini dans Request.java:Pourquoi JPA ne supprime-t-il pas les entités possédées lorsque l'entité propriétaire perd leur référence?

@OneToMany(cascade= CascadeType.ALL, mappedBy="request") 
private List<Answer> answerList; 

Et Answer.java:

@JoinColumn(name = "request", referencedColumnName="id") 
@ManyToOne(optional = false) 
private Request request; 

Au cours de l'exécution du programme, la liste des réponses de la demande peut avoir des réponses ajoutés ou supprimés de celui-ci, ou l'objet List réel peut être remplacé. Mon problème est ainsi: quand je fusionne une demande à la base de données, les objets de réponse utilisés pour être dans la liste sont conservés dans la base de données - c'est-à-dire, les objets de réponse que la demande ne contient plus (indirectement, via une liste) ne sont pas supprimés.

Ce n'est pas le comportement que je souhaite, comme si je fusionne une demande à la base de données, puis la récupère à nouveau, sa liste de réponses peut ne pas être la même. Est-ce que je fais une erreur de programmation? Existe-t-il une annotation ou un paramètre qui garantira que les réponses dans la base de données sont exactement les réponses dans la liste des demandes?

Une solution consiste à conserver les références à la liste des réponses d'origine, puis à utiliser EntityManager pour supprimer chaque ancienne réponse avant de fusionner la demande, mais il semble qu'il devrait y avoir une méthode plus propre.

Répondre

1

Dans JPA 1.0, ce que vous voulez faire ne peut pas être fait par JPA. Simplement, toute la gestion des relations doit être effectuée par l'application, y compris la suppression des orphelins des collections (ce que vous essayez de faire).

Dans JPA 2.0, ils prennent en charge (bien que je ne connaisse pas les détails), mais en fonction de votre implémentation, une mise à niveau peut ne pas être facile ou possible.

Vous pouvez également utiliser quelque chose comme Hibernate directement, mais encore utiliser de nombreuses annotations JPA 1.0, etc. Je ne peux pas non plus fournir de détails à ce sujet.

Dans mon cas, j'ai écrit du code générique pour gérer la fusion automatique de collections par réflexion.

+2

Dans Hibernate, ceci peut être fait en utilisant CascadeType.DELETE_ORPHAN. –

0

Il est illégal de spécifier des propriétés supplémentaires dans une relation mappée. Vous pouvez utiliser l'annotation @DependentElement dans Request à la place.

+0

@DependentElement fait partie de la spécification JPA? Je n'ai jamais croisé mon chemin avant. – bert

1

L'utilisation d'EclipseLink et l'ajout d'annotations @PrivateOwned à answerList vous aideraient.

0

Si vous utilisez Hibernate en tant que fournisseur JPA, vous pouvez ajouter un

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

sur le answerList. Cela fonctionnerait en plus des annotations JPA que vous utilisez déjà. JPA 2 (la plupart des fournisseurs JPA n'ont pas d'implémentation prête pour la production pour l'instant) peuvent le faire seuls.

Questions connexes