J'ai deux objets utilisateur et pendant que j'essaye de sauvegarder l'objet en utilisant
session.save(userObj);
Je reçois l'erreur suivante:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
Je crée la session en utilisant
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(),
BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close(); // in finally block
J'ai aussi essayé de faire la session.clear()
sauvegarde avant, toujours pas de chance.
C'est pour la première fois que j'obtiens l'objet de session lorsqu'une demande d'utilisateur arrive, donc je comprends pourquoi je dis que cet objet est présent dans la session.
Aucune suggestion?
Réponses:
J'ai eu cette erreur plusieurs fois et cela peut être assez difficile à retrouver ...
En gros, ce que dit hibernate, c'est que vous avez deux objets qui ont le même identifiant (même clé primaire) mais qui ne sont pas le même objet.
Je vous suggère de décomposer votre code, c'est-à-dire de commenter les bits jusqu'à ce que l'erreur disparaisse, puis de remettre le code jusqu'à ce qu'il revienne et que vous devriez trouver l'erreur.
Cela se produit le plus souvent via des sauvegardes en cascade où il y a une sauvegarde en cascade entre les objets A et B, mais l'objet B a déjà été associé à la session mais n'est pas sur la même instance de B que celle sur A.
Quel générateur de clé primaire utilisez-vous?
La raison pour laquelle je pose la question est que cette erreur est liée à la façon dont vous dites à hibernate de vérifier l'état persistant d'un objet (c'est-à-dire si un objet est persistant ou non). L'erreur peut se produire parce que la mise en veille prolongée tente de conserver un objet qui est déjà persistant. En fait, si vous utilisez save hibernate, vous essaierez de conserver cet objet, et peut-être qu'il y a déjà un objet avec cette même clé primaire associée à la session.
Exemple
En supposant que vous ayez un objet de classe de mise en veille prolongée pour une table de 10 lignes basée sur une combinaison de clés primaires (colonne 1 et colonne 2). Maintenant, vous avez supprimé 5 lignes du tableau à un moment donné. Maintenant, si vous essayez à nouveau d'ajouter les mêmes 10 lignes, tandis que Hibernate tente de conserver les objets dans la base de données, 5 lignes qui ont déjà été supprimées seront ajoutées sans erreur. Maintenant, les 5 lignes restantes qui existent déjà, lèveront cette exception.
Donc, l'approche simple serait de vérifier si vous avez mis à jour / supprimé une valeur dans une table qui fait partie de quelque chose et que vous essayez plus tard d'insérer à nouveau les mêmes objets
la source
Ce n'est qu'un point où la mise en veille prolongée pose plus de problèmes qu'elle n'en résout. Dans mon cas, il y a beaucoup d'objets avec le même identifiant 0, car ils sont nouveaux et n'en ont pas. La base de données les génère. Quelque part, j'ai lu que 0 signaux Id non défini. La façon intuitive de les conserver est de les parcourir et de dire hibernate pour enregistrer les objets. Mais vous ne pouvez pas faire ça - "Bien sûr, vous devriez savoir que la mise en veille prolongée fonctionne de cette façon, donc vous devez ..." Alors maintenant je peux essayer de changer les identifiants en Long au lieu de long et voir si cela fonctionne. En fin de compte, il est plus facile de le faire avec un simple mappeur, car la mise en veille prolongée n'est qu'un fardeau supplémentaire intransparent. Un autre exemple: essayer de lire les paramètres d'une base de données et de les conserver dans une autre vous oblige à faire presque tout le travail manuellement.
la source
UTILISATION
session.evict(object);
La fonction deevict()
méthode est utilisée pour supprimer une instance du cache de session. Donc, pour la première fois que vous enregistrez l'objet, enregistrez l'objet en appelant lasession.save(object)
méthode avant d'expulser l'objet du cache. De la même manière, mettez à jour l'objet en appelantsession.saveOrUpdate(object)
ousession.update(object)
avant d'appeler evict ().la source
Cela peut se produire lorsque vous avez utilisé le même objet de session pour la lecture et l'écriture. Comment? Supposons que vous ayez créé une session. Vous avez lu un enregistrement de la table des employés avec la clé primaire Emp_id = 101 Vous avez maintenant modifié l'enregistrement en Java. Et vous allez enregistrer l'enregistrement de l'employé dans la base de données. nous n'avons fermé nulle part ici. Comme l'objet qui a été lu, persiste également dans la session. Il entre en conflit avec l'objet que nous souhaitons écrire. D'où cette erreur.
la source
Comme quelqu'un l'a déjà souligné ci-dessus, j'ai rencontré ce problème lorsque j'avais
cascade=all
aux deux extrémités d'uneone-to-many
relation, supposons donc A -> B (un-à-plusieurs de A et plusieurs-à-un de B) et mettait à jour l'instance de B dans A, puis en appelant saveOrUpdate (A), cela entraînait une demande de sauvegarde circulaire, c'est-à-dire que la sauvegarde de A déclenche la sauvegarde de B qui déclenche la sauvegarde de A ... et dans la troisième instance, l'entité (de A) a été tentée de être ajouté à sessionPersistenceContext, l'exception duplicateObject a été levée.Je pourrais le résoudre en supprimant la cascade d'une extrémité.
la source
Vous pouvez utiliser
session.merge(obj)
, si vous effectuez une sauvegarde avec différentes sessions avec le même objet persistant identifiant.Cela a fonctionné, j'avais le même problème avant.
la source
J'ai également rencontré ce problème et j'ai eu du mal à trouver l'erreur.
Le problème que j'ai eu était le suivant:
L'objet a été lu par un Dao avec une session d'hibernation différente.
Pour éviter cette exception, relisez simplement l'objet avec le dao qui va sauvegarder / mettre à jour cet objet plus tard.
alors:
J'espère que cela fera gagner beaucoup de temps à certaines personnes!
la source
J'ai rencontré ce problème par:
Je l'ai résolu en vidant les résultats après la suppression et en effaçant le cache avant d'enregistrer le nouvel objet
la source
Ce problème se produit lorsque nous mettons à jour le même objet de session, que nous avons utilisé pour récupérer l'objet de la base de données.
Vous pouvez utiliser la méthode de fusion de la mise en veille prolongée au lieu de la méthode de mise à jour.
Par exemple, utilisez d'abord session.get () et ensuite vous pouvez utiliser session.merge (object). Cette méthode ne créera aucun problème. Nous pouvons également utiliser la méthode merge () pour mettre à jour l'objet dans la base de données.
la source
Récupérez l'objet dans la session, voici un exemple:
la source
Vos mappages d'identifiants sont-ils corrects? Si la base de données est responsable de la création de l'ID via un identifiant, vous devez mapper votre objet utilisateur à celui-ci.
la source
J'ai rencontré ce problème avec la suppression d'un objet, ni expulser ni effacer aidé.
la source
avant la position où commencent les objets répétitifs, vous devez fermer la session, puis démarrer une nouvelle session
ainsi, dans une session, il n'y a pas plus d'une entité qui a le même identifiant.
la source
En retard à la fête, mais peut aider pour les utilisateurs à venir -
J'ai eu ce problème lorsque je sélectionne un enregistrement à l'aide
getsession()
et que je mets à nouveau à jour un autre enregistrement avec le même identifiant en utilisant la même session provoque le problème. Code ajouté ci-dessous.Cela ne devrait jamais être fait. La solution consiste soit à expulser la session avant la mise à jour, soit à modifier la logique métier.
la source
Vérifiez si vous avez oublié de mettre @GenerateValue pour la colonne @Id. J'ai eu le même problème avec la relation plusieurs à plusieurs entre le film et le genre. Le programme a lancé une erreur Hibernate: org.hibernate.NonUniqueObjectException: un objet différent avec la même valeur d'identifiant était déjà associé à l'erreur de session. J'ai découvert plus tard que je dois juste m'assurer que vous avez @GenerateValue à la méthode get de GenreId.
la source
il suffit de vérifier l'identifiant s'il prend nul ou 0 comme
dans ajouter ou mettre à jour où le contenu est défini du formulaire à Pojo
la source
Je suis nouveau sur NHibernate, et mon problème était que j'ai utilisé une session différente pour interroger mon objet que pour le sauvegarder. La session de sauvegarde ne connaissait donc pas l'objet.
Cela semble évident, mais à la lecture des réponses précédentes, je cherchais partout 2 objets, pas 2 sessions.
la source
@GeneratedValue (strategy = GenerationType.IDENTITY), l'ajout de cette annotation à la propriété de clé primaire dans votre bean entité devrait résoudre ce problème.
la source
J'ai résolu ce problème.
En fait, cela se produit parce que nous avons oublié l'implémentation de la propriété Generator Type of PK dans la classe bean. Alors faites-en n'importe quel type comme
quand on persiste les objets du bean, chaque objet acquiert le même identifiant, donc le premier objet est sauvegardé, quand un autre objet à persister alors HIB FW à travers ce type d'
Exception: org.hibernate.NonUniqueObjectException:
objet différent avec la même valeur d'identifiant était déjà associé à la session.la source
Le problème se produit car dans la même session de mise en veille prolongée, vous essayez de sauvegarder deux objets avec le même identifiant.Il y a deux solutions: -
Cela se produit car vous n'avez pas configuré correctement votre fichier mapping.xml pour les champs id comme ci-dessous: -
Surchargez la méthode getsession pour accepter un paramètre comme isSessionClear, et effacez la session avant de retourner la session en cours comme ci-dessous
Cela entraînera l'effacement des objets de session existants et même si hibernate ne génère pas d'identifiant unique, en supposant que vous ayez correctement configuré votre base de données pour une clé primaire en utilisant quelque chose comme Auto_Increment, cela devrait fonctionner pour vous.
la source
J'avais un problème similaire. Dans mon cas, j'avais oublié de définir la
increment_by
valeur dans la base de données pour qu'elle soit la même que celle utilisée parcache_size
etallocationSize
. (Les flèches pointent vers les attributs mentionnés)SQL:
Java:
la source
A part ce que dit wbdarby , cela peut même arriver lorsqu'un objet est récupéré en donnant l'identifiant de l'objet à un HQL. Dans le cas où vous essayez de modifier les champs de l'objet et de le sauvegarder dans la base de données (la modification peut être une insertion, une suppression ou une mise à jour) au cours de la même session , cette erreur apparaîtra. Essayez d'effacer la session de mise en veille prolongée avant d'enregistrer votre objet modifié ou de créer une nouvelle session.
J'espère avoir aidé ;-)
la source
J'ai la même erreur que je remplaçais mon ensemble par un nouveau obtenu de Jackson.
Pour résoudre ce problème, je garde l'ensemble existant, je supprime de l'ancien ensemble l'élément inconnu dans la nouvelle liste avec
retainAll
. Ensuite, j'ajoute les nouveaux avecaddAll
.Pas besoin d'avoir la Session et de la manipuler.
la source
Essaye ça. Le ci-dessous a fonctionné pour moi!
Dans le
hbm.xml
dossierNous devons définir l'
dynamic-update
attribut de la balise de classe surtrue
:Définissez l'attribut de classe de la balise du générateur sous une colonne unique sur
identity
:Remarque: définissez la colonne unique sur
identity
plutôt queassigned
.la source
Une autre chose qui a fonctionné pour moi a été de rendre la variable d'instance Long au lieu de long
J'avais mon id long de variable de clé primaire; le changer en Long id; travaillé
Bonne chance
la source
Vous pouvez toujours faire un vidage de session. Flush synchronisera l'état de tous vos objets en session (s'il vous plaît, quelqu'un me corrige si je me trompe), et peut-être que cela résoudrait votre problème dans certains cas.
L'implémentation de vos propres égaux et hashcode peut également vous aider.
la source
Vous pouvez vérifier vos paramètres de cascade. Les paramètres Cascade de vos modèles peuvent être à l'origine de ce problème. J'ai supprimé les paramètres de cascade (essentiellement n'autorisant pas les insertions / mises à jour en cascade) et cela a résolu mon problème
la source
J'ai également trouvé cette erreur. Ce qui a fonctionné pour moi, c'est de m'assurer que la clé primaire (qui est automatiquement générée) n'est pas un PDT (c'est-à-dire long, int, ect.), Mais un objet (c'est-à-dire Long, Integer, etc.)
Lorsque vous créez votre objet pour l'enregistrer, assurez-vous de transmettre null et non 0.
la source
est-ce que cela aide?
la source
J'ai résolu un problème similaire comme celui-ci:
la source