128 votes

Erreur Hibernate : un objet différent avec la même valeur d'identifiant a déjà été associé à la session.

J'ai essentiellement quelques objets dans cette configuration (le modèle de données réel est un peu plus complexe) :

  • A a une relation de plusieurs à plusieurs avec B. (B a inverse="true" )
  • B a une relation de plusieurs à un avec C. (J'ai cascade réglé sur "save-update" )
  • C est une sorte de tableau de types/catégories.

En outre, je devrais probablement mentionner que les clés primaires sont générées par la base de données lors de la sauvegarde.

Avec mes données, je rencontre parfois des problèmes où A possède un ensemble d'objets B différents, et ces objets B font référence au même objet C.

Quand j'appelle session.saveOrUpdate(myAObject) j'ai une erreur d'hibernation qui dit : "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 existe-t-il un moyen de contourner ce problème ? Il semble que cette situation ne soit pas si rare.

Au cours de mes recherches sur ce problème, j'ai vu des personnes suggérer l'utilisation de session.merge() Mais lorsque je fais cela, tous les objets "conflictuels" sont insérés dans la base de données en tant qu'objets vides avec toutes les valeurs définies comme nulles. Il est clair que ce n'est pas ce que nous voulons.

[Une autre chose que j'ai oublié de mentionner est que (pour des raisons architecturales indépendantes de ma volonté), chaque lecture ou écriture doit être effectuée dans une session séparée.

7voto

user2845946 Points 796

Transférez la tâche d'attribution de l'ID d'objet d'Hibernate à la base de données en utilisant :

<generator class="native"/>

Cela a résolu le problème pour moi.

5voto

user158037 Points 2198

Dans un autre cas, lorsque le même message d'erreur peut être généré, il est possible de personnaliser le message. allocationSize :

@Id
@Column(name = "idpar")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "paramsSequence")
@SequenceGenerator(name = "paramsSequence", sequenceName = "par_idpar_seq", allocationSize = 20)
private Long id;

sans correspondance

alter sequence par_idpar_seq increment 20;

peut provoquer la validation des contraintes pendant l'insertion (ce cas est facile à comprendre) ou le cas "un objet différent avec la même valeur d'identifiant était déjà associé à la session" - ce cas était moins évident.

4voto

Waqar Points 11

Une façon de résoudre le problème ci-dessus consistera à remplacer l'attribut hashcode() .
Videz également la session d'hibernation avant et après la sauvegarde.

getHibernateTemplate().flush();

En définissant explicitement l'objet détaché en tant que null aide également.

3voto

Hemant kumar Points 41

Ajouter l'annotation @ValeurGénérée au haricot que vous insérez.

2voto

Je viens de tomber sur ce message mais en code c#. Je ne sais pas si c'est pertinent (c'est exactement le même message d'erreur).

Je déboguais le code avec des points d'arrêt et j'ai étendu certaines collections par le biais de membres privés alors que le débogueur était à un point d'arrêt. Après avoir réexécuté le code sans fouiller dans les structures, le message d'erreur a disparu. Il semble que l'acte de regarder dans les collections privées chargées paresseusement a fait que NHibernate charge des choses qui n'étaient pas censées être chargées à ce moment-là (parce qu'elles étaient dans des membres privés).

Le code lui-même est enveloppé dans une transaction assez compliquée qui peut mettre à jour un grand nombre d'enregistrements et de nombreuses dépendances dans le cadre de cette transaction (processus d'importation).

J'espère qu'il s'agit d'un indice pour tous ceux qui rencontrent ce problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X