Pourquoi ne JPA supprimer des entités détenues lorsque l'entité propriétaire perd la référence à eux?

StackOverflow https://stackoverflow.com/questions/1133179

  •  16-09-2019
  •  | 
  •  

Question

J'ai une entité JPA « Demande », qui possède une liste de réponses (aussi entités JPA). Voilà comment il est défini dans Request.java:

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

Et dans Answer.java:

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

Au cours de l'exécution du programme, peut avoir des réponses ajoutés ou retirés de celui-ci, ou l'objet de la liste réelle peut être remplacé Liste des réponses de la demande. Mon problème est donc: quand je fusionner une demande de la base de données, les objets de réponse que utilisés dans la liste sont conservés dans la base de données - à savoir, réponse des objets que la demande ne détient plus référence (indirectement, par l'intermédiaire d'une liste) ne sont pas supprimés.

Ce n'est pas le comportement que je veux, comme si je fusionner une demande à la base de données, puis vient le chercher à nouveau, sa liste de réponses peut ne pas être la même chose. Est-ce que je fais une erreur de programmation? Y at-il une annotation ou un paramètre qui fera en sorte que les réponses dans la base de données sont exactement les réponses dans la liste de la demande?

Une solution est de garder les références à la liste des réponses originales, puis utilisez le EntityManager pour supprimer chaque ancienne réponse avant de fusionner la demande, mais il semble qu'il devrait y avoir un moyen plus propre.

Était-ce utile?

La solution

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

Dans JPA 2.0, ils le soutien (bien que je ne connais pas les détails), mais en fonction de votre mise en œuvre, une mise à niveau ne peut pas être facile ou possible.

Vous pouvez également utiliser quelque chose comme Hibernate directement, mais toujours utiliser de nombreuses annotations JPA 1.0, etc. Je ne peux pas fournir des détails sur ce soit.

Dans mon cas, je l'ai écrit code générique pour gérer la fusion des collections automatiquement par la réflexion.

Autres conseils

Utilisation EclipseLink et de mettre l'annotation @PrivateOwned à answerList serait utile.

Il est illégal de spécifier des propriétés supplémentaires par rapport cartographié. Vous pouvez utiliser l'annotation @DependentElement dans la demande à la place.

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

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

sur la answerList. Cela fonctionnerait, en plus de l'Assemblée parlementaire paritaire annotations que vous utilisez déjà. JPA 2 (plus / tous les fournisseurs JPA ne dispose pas d'une mise en œuvre de la production prête à ce moment) peut le faire lui-même.

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