Hibernate Erreur: un objet différent avec le même identifiant de la valeur a déjà été associé à la session
J'ai, pour l'essentiel, certains objets dans cette configuration (le vrai modèle de données est un peu plus complexe):
- Un a un plusieurs-à-plusieurs relation avec B. B a
inverse="true"
) - B a une many-to-one relation avec C. (j'ai
cascade
ensemble de"save-update"
) - C est une sorte de type/catégorie de la table.
Aussi, je devrais probablement mentionner que les clés primaires sont générés par la base de données sur enregistrer.
Avec mes données, j'ai parfois courir dans des problèmes où l'Un a un ensemble différent de B des objets, et ces objets font référence au même objet C.
Quand je l'appelle session.saveOrUpdate(myAObject)
, je reçois un hibernate erreur disant: "a different object with the same identifier value was already associated with the session: C"
. Je sais qu'hibernate ne peut pas insérer/mettre à jour/supprimer le même objet deux fois dans la même session, mais est-il un moyen de contourner cela? Cela ne semble pas comme il le serait si rare d'une situation.
Au cours de mes recherches sur ce problème, j'ai vu des gens suggèrent l'utilisation de session.merge()
, mais quand je fais ça, tout "conflit" des objets insérés dans la base de données vide d'objets avec toutes les valeurs null. Clairement ce n'est pas ce que nous voulons.
[Modifier] une Autre chose que j'ai oublié de mentionner, c'est que (pour des raisons d'architecture au-delà de mon contrôle), chaque lecture ou écriture doit être fait dans une autre session.
- Voir si cette answer aide à vous..
Vous devez vous connecter pour publier un commentaire.
Très probablement son parce que le B objets ne sont pas référence à la même Java C instance de l'objet. Ils font référence à la même ligne dans la base de données (c'est à dire la même clé primaire), mais ils sont différents des copies.
Donc ce qui se passe, c'est que la session Hibernate, qui est la gestion des entités à maintenir la trace de l'objet Java correspond à la ligne avec la même clé primaire.
Une option serait de faire en sorte que les Entités d'objets B qui se réfèrent à la même ligne sont en réalité référence à la même instance d'objet de C. Sinon éteindre en cascade pour cette variable membre. De cette façon, lorsque B est a persisté C ne l'est pas. Vous aurez à sauver C manuellement séparément. Si C est un type/catégorie de la table, puis elle est probablement du sens d'être de cette façon.
Juste mis en cascade de FUSION, qui devrait faire l'affaire.
Vous avez seulement besoin de faire une chose. Exécuter
session_object.clear()
et puis enregistrez le nouvel objet. C'est clair la session (comme le bien nommé) et de supprimer le contenu litigieux copie de l'objet à partir de votre session.Je suis d'accord avec @Hemant Kumar, merci beaucoup. Selon sa solution, j'ai résolu mon problème.
Par exemple:
Person.java
Ce code toujours faire d'erreur dans ma demande:
A different object with the same identifier value was already associated with the session
, plus tard, j'ai découvert que j'ai oubliépour autoincrease ma clé primaire!
Ma solution est d'ajouter ce code sur votre clé primaire:
Transfert de la tâche d'attribuer l'ID de l'objet de mise en veille prolongée à la base de données à l'aide de:
Cela a résolu le problème pour moi.
Ajouter l'annotation
@GeneratedValue
de la fève à insérer.
Une manière de résoudre le problème ci-dessus seront à remplacer la
hashcode()
.Également vider la session hibernate avant et après l'enregistrer.
La définition explicite de la détacher de l'objet à
null
contribue également.Cela signifie que vous essayez d'enregistrer plusieurs lignes de votre table avec la référence au même objet.
vérifier votre Classe d'Entité' id de propriété.
à
Viens de tomber sur ce message, mais dans le code c#. Vous ne savez pas si elle est pertinente, (exactement le même message d'erreur si).
J'ai été débogage du code avec des points d'arrêt et l'étendue de certaines collections privées membres, tandis que le débogueur a été à un point d'arrêt. Après avoir ré-exécuter le code sans creuser par le biais de structures faites le message d'erreur s'en aller. Il semble que la loi de la recherche dans le secteur privé chargement paresseux collections a NHibernate charge des choses qui n'étaient pas censés être chargé à l'époque (parce qu'ils ont été privés de leurs membres).
Le code est lui-même enveloppé dans un assez transaction complexe qui peut mettre à jour un grand nombre d'enregistrements et de nombreuses dépendances dans le cadre de cette transaction (processus d'importation).
Espérons le, une idée à quelqu'un d'autre qui vient à travers la question.
Trouver la "Cascade" attribut en Hibernation et de le supprimer. Lorsque vous définissez la "Cascade", il va en appeler d'autres opérations (enregistrer, mettre à jour et supprimer) sur un autre entités qui a relation avec les classes connexes. Donc même les identités de valeur sera arrivé.
Il a travaillé avec moi.
J'ai eu cette erreur quelques jours et j'ai accéléré trop de temps à corriger cette erreur.
Avant, j'obtiens cette erreur , je n'avais pas mentionné génération de code type sur la OrderDetil Objet. lorsque, sans générer de Orderdetails' id il garde Id 0 pour tout OrderDetail objets. ce que #jbx expliqué. Oui c'est la meilleure réponse. cet exemple, comment ça se passe.
Essayer de placer le code de votre requête avant.
Que pour résoudre mon problème.
par exemple, modifiez ce qui suit:
à ceci:
vous pourriez ne pas être en paramètre l'identifiant de l'objet avant l'appel de requête de mise à jour.
J'ai rencontré le problème à cause de la clé primaire de la génération est mal,quand j'insère une ligne comme ceci:
- Je changer l'id du générateur de classe à l'identité
Dans mon cas, seule la méthode flush() ne fonctionne pas. J'ai dû utiliser un clear() après flush().
si vous utilisez l'objet entityrepository ensuite utiliser saveAndFlush au lieu de sauver
Si elle reste une des expressions de l'onglet dans mon IDE open de faire une veille prolongée obtenir de l'appel sur l'objet à l'origine de cette exception. J'ai essayé de supprimer ce même objet. Aussi, j'ai eu un point d'arrêt sur la suppression de l'appel qui semble être nécessaire pour obtenir cette erreur se produise. Simplement en faisant une autre des expressions onglet à l'avant de l'onglet ou la modification du paramètre de sorte que l'ide ne pas s'arrêter sur des points d'arrêt de résoudre ce problème.