2010-07-14 6 views
5

Pourquoi j'ai besoin de la ligne "session.save (user);" dans l'extrait de code suivant? Je pensais, avec l'appel de trouver l'utilisateur est déjà attaché à la session et les changements seront suivis et validés. Pourriez-vous m'expliquer les détails pour moi? Ou ai-je besoin d'une configuration spéciale ou d'autres circonstances où j'aurais pu entendre parler de cette 'fonctionnalité'?Pourquoi dois-je sauvegarder explicitement après une recherche avec Hibernate?

session = createSession(); 
ta = session.beginTransaction(); 
assertEquals(1, session.createCriteria(MyUser.class).list().size()); 
// find one user 
MyUser user = session.createCriteria(MyUser.class).uniqueResult(); 
user.setName("Rocker!"); 
// ### HERE ### 
// WHY this 'save' is necessary!!?? 
session.save(user); 
ta.commit(); 

ta = session.beginTransaction(); 
assertEquals(1, session.createCriteria(MyUser.class).list().size()); 
MyUser user = session.createCriteria(MyUser.class).uniqueResult(); 
assertEquals("Rocker!", user.getName()); 
ta.commit(); 

UPDATE 1

La même question vaut pour

  1. session.save (utilisateur);
  2. user.setName ("Rocker!");
  3. ta.commit();

MISE À JOUR 2

La solution au problème est: Je me sers persiste Guice/chaîne. Et dans certains cas, un bloc de code a été lié de manière incorrecte à une transaction via @Transactional: la transaction a donc été validée trop tôt et le changement séparé n'a donc pas été inclus dans le commit. Merci les gars! Donc, assurez-vous toujours connaître votre champ de transaction dans le cas où vous utilisez printemps ou Guice ...

+0

avez-vous activé la journalisation hibernate pour examiner ce qui se passe entre le retour de uniqueresult() et commit()? –

+0

Je l'ai toujours fait avec cet 'save' explicite les derniers mois avec hibernate. jusqu'à aujourd'hui: où je l'ai demandé moi-même. Je vais jeter un coup d'oeil dans les journaux. Mais regardez mon édition ci-dessous le code: la sauvegarde explicite est également nécessaire après que j'ai déjà appelé la sauvegarde – rocker

+0

bien quand quelque chose fonctionne depuis longtemps "jusqu'à aujourd'hui" et le code n'a pas changé, cela implique une certaine configuration ailleurs a changé - être Assurez-vous de revoir ce qui a exactement changé dans l'ensemble du projet/application depuis le dernier état de travail connu. De toute évidence, les choses ne s'arrêtent pas juste de fonctionner. –

Répondre

5

Vous avez raison hibernate automatiquement détecter les changements à l'état d'objets persistants:

persistante - une instance persistante a une représentation dans la base de données et une valeur d'identifiant. Il pourrait simplement avoir été sauvegardé ou chargé, cependant, il est par définition dans le cadre d'une session. Hibernate détectera les modifications apportées à un objet dans un état persistant et synchronisera l'état avec la base de données lorsque l'unité de travail sera terminée. Les développeurs n'exécutent pas d'instructions UPDATE manuelles ou d'instructions DELETE lorsqu'un objet doit être rendu transitoire.

Je suppose que les résultats de critères ne sont pas retournés dans un état persistant (mais je ne peux pas sembler trouver la preuve dans les docs)

Essayez d'utiliser une requête HQL, pour lequel les documents sont clair:

instances d'entité récupérées par une requête sont dans un état persistant

assurez-vous également que le mode de rinçage de la session est réglée sur AUTO o r COMMIT.

+0

Le mode de vidage 'AUTO' - est-ce par défaut et comment puis-je le changer? – rocker

+0

Avec la requête HQL, c'est la même chose: une sauvegarde explicite (après quelque chose de changé) est nécessaire. – rocker

+1

@rocker, 'session.setFlushMode (FlushMode.AUTO)'. –

Questions connexes