JPA efface la collection et ajoute de nouveaux articles
J'ai un @OneToMany collection (liste) que je tiens à clarifier et d'ajouter de nouveaux éléments dans la même transaction.
À l'aide de
collection.clear();
collection.add(new EntityB());
Ajoute simplement la nouvelle instance, et ne supprime jamais rien. J'ai orphanRemoval = true
pour la collecte de terrain.
AJOUTÉ:
//Parent entity
@OneToMany(mappedBy = "product", orphanRemoval = true)
private List<Feature> features = new ArrayList<>();
//Child entity
@ManyToOne(cascade = CascadeType.ALL)
private Product product;
//Clear and add attempt
product.getFeatures().clear();
Feature feature = new Feature(product, ls);
product.getFeatures().add(feature);
source d'informationauteur Dennis Thrysøe
Vous devez vous connecter pour publier un commentaire.
Vous essayez d'effacer un seul côté de la bidirectionnel de l'association.
Ainsi, au lieu de:
Comme expliqué dans cet articleessayer de nettoyer les deux côtés et cela devrait fonctionner:
Retirer également la cascade de
@ManyToOne
et le déplacer vers@OneToMany
.L'esprit les contraintes
Toutefois, si vous avez une contrainte unique, ce
clear + add
Anti-Modèle ne fonctionnera pas car l'action d'INSERTION est exécutée avant la SUPPRESSION de l'un comme expliqué dans cet article.La bonne façon de le faire est de vérifier les entrées qui doivent être enlevés et simplement de les supprimer. Ensuite, ajouter les nouveaux, et de mettre à jour ceux que l'a modifié. C'est une façon de faire une collection de fusionner correctement.
S'avère que la solution était d'utiliser un @JoinColumn annotation au lieu de la mappedBy=" paramètre".
Cela semble vraiment être un bug dans de nombreuses versions de mise en veille prolongée. Je l'ai testé avec EclipseLink et ça fonctionne sans problème.
Comme solution de contournement dans Hibernate (testé en mode veille prolongée 4.3.6-Finale): Supprimer toute en cascade dans le
Feature
entité, et ajouterCascadeType.PERSIST
(ouCascadeType.ALL
) dans leProduct
entité.Juste pour s'assurer que cela ne fonctionne pas, essayez les solutions suivantes:
Dans la Section 2.9, entités-Relations, la JPA 2.1 spécification dit:
Êtes-vous sûr que votre entité est gérée dans le contexte de persistance lorsque vous la retirez de la collection?
Vous pouvez y remédier en utilisant
fetch=fetchType.EAGER
ou parfetch joins
. Sinon (ça dépend de votre cas d'utilisation), il peut être suffisante pour définir appropriécascade
option.J'ai fait face à un problème similaire récemment. Pour moi, le problème était que les orphelins étaient encore référencé à partir d'une autre entité gérée, et il y avait un PERSISTER en cascade défini par la relation:
Supposons que toutes les entités concernées sont gérées, c'est à dire chargé dans le contexte de persistance. Maintenant, nous faisons la même chose que l'OP:
Du point de vue philosophique, le problème ici est que le modèle d'objet devient incohérent si vous ne retirez la Fonction à partir de l'entité de Produit, mais pas à partir de la Description de l'entité. Après tout, vous voulez la Fonction à être supprimé, mais il est toujours référencé à partir d'autres objets. Techniquement, ce qui se passe est qu'il y a deux tendances contradictoires cascadings aller à la Fonctionnalité de l'entité, et le résultat peut dépendre de l'ordre dans lequel elles sont appliquées.
Depuis la Fonctionnalité a été supprimée de la collecte des produits, l'orphelin de suppression s'applique, et la Fonction de l'entité de transitions à la "suppression" de l'état au cours de la prochaine chasse d'eau, comme indiqué dans la JPA 2.1 spec (2.9). J'ai ajouté l'accent sur les parties pertinentes:
Cependant, la même Fonction est toujours référencé à partir d'une Description de l'entité, qui a PERSISTER en cascade vers la Fonctionnalité. La JPA 2.1 spécification dit le texte suivant:
Donc cette cascade va effectuer un "persist" fonctionnement sur la Caractéristique de l'entité, même si nous ne les appelons pas em.persist() sur la Description. C'est suffisant pour la Description à être gérés lorsqu'une couleur est réalisée afin de déclencher cette persistent en cascade.
Cela signifie que nous sommes en train de faire exactement ce que la spécification nous a dit que nous ne devrions pas performants orphelin de l'enlèvement et de la persistance sur la même entité. Ce qui semble se produire dans la pratique en veille prolongée, c'est que les deux opérations sont appliquées à leur tour. D'abord l'opération de suppression rend la Fonction de l'entité de transition à la "suppression" de l'état, puis la poursuite de l'opération tourne à la disparition de l'entité de retour dans un gérées. En conséquence, la Fonctionnalité n'est pas supprimé de la base de données.