2010-08-17 16 views
3

J'utilise Hibernate entity manager 3.5.1-Final avec MS SQL Server 2005 et j'essaie de conserver plusieurs nouvelles entités. Mon entité est annotationally configuré ainsi:JPA/Hibernate/MS SQL Server ne renvoie pas la valeur de l'ID généré

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private int id; 

Après avoir appelé

entityManager.persist(newEntity) 

Je ne vois pas l'ensemble generatedId, il reste à 0. Cela provoque l'exception suivante lors de la persistance de la prochaine nouvelle entité:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [x.y.z.MyEntity#0] 

Je peux contourner cela en expulsant l'entité récemment persistée du cache avant de persister l'entité suivante, mais ce n'est pas l'idéal. Que dois-je faire pour mettre à jour l'objet correctement après insertion?

Répondre

0

Je ne vois pas l'ensemble generatedId, il reste comme 0.

Le code annoté lui-même semble correct (vous pouvez utiliser IDENTITY avec long, short, integer types - et leurs respectifs types de wrapper - et String). Maintenant, les questions sont:

  • utilisez-vous vraiment une colonne d'identité sur le côté db (s'il vous plaît montrer votre définition de table)?
  • quelle instruction SQL est réellement effectuée (activer la journalisation SQL)? Que se passe-t-il si vous exécutez le SQL généré dans un client SQL?

Je peux contourner ce en expulsant l'entité récemment persisté à partir du cache avant la prochaine entité persiste, mais ce n'est pas idéal.

Ceci n'est clairement pas une solution. L'identifiant généré doit être affecté à l'entité persistante et tout autre comportement est inattendu. Il y a certainement une discordance quelque part qui doit être réparée. S'il vous plaît fournir les informations demandées.

+0

J'ai trouvé le problème - c'était une table héritée et je ne me suis pas rendu compte qu'il y avait un déclencheur INSTEAD OF INSERT sur la table qui déformait la valeur @@ IDENTITY transmise à Hibernate. – timbotoolman

0

Utilisez un entier "I" majuscule.

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
private Integer id; 
+0

Cela ne semble pas faire la différence. Le rinçage après chaque insertion n'est pas non plus possible. – timbotoolman

+0

Donc si vous persistez juste un objet, apparaît-il réellement dans la base de données? Si oui, avez-vous remplacé les méthodes égales et hashcode, peuvent-elles retourner les mauvaises valeurs? Avez-vous essayé de définir les annotations sur le getId() au lieu du champ? Avez-vous défini des getters et setters? S'il vous plaît nous fournir plus de détails. –

+0

En outre, utilisez-vous "auto_increment" sur l'ID lorsque vous créez la table? Créer TABLE XXX ('id' int NOT NULL AUTO_INCREMENT, etc.) –

2

J'ai eu un problème similaire que je et cela a fonctionné analysé les causes pour moi:

em.persist({ENTITY_TO_PERSIST}); 
em.flush(); 
em.refresh({ENTITY_TO_PERSIST}); 

La méthode refresh () a fait l'affaire.

REMARQUE: Dans ma réponse, j'ai supposé que votre table de base de données était correctement configurée avec sa spécification d'identité définie sur "yes" pour la colonne en question.