29 votes

Hibernate: inconvénient de la fusion () par rapport à la mise à jour ()

Je vais avoir des problèmes avec un NonUniqueObjectException lancée par Hibernate.

La lecture de la documentation, et de ce blog, j'ai remplacé l'appel à partir d' update() de merge(), et il a résolu le problème.

Je crois que je comprends la raison de l'exception, et pourquoi la modification de la méthode a résolu le problème, en termes d'objets déconnectés de la session et de limites.

Ma question est : étant donné qu' merge() toujours résoudre à la session de l'objet ou de le récupérer s'il n'existe pas, appelle merge() est généralement une alternative plus sûre que d' update()?

Quel est l'inconvénient de l'utilisation de merge() sur update()?

41voto

Arthur Ronald Points 19001

Appelle merge() est généralement une alternative plus sûre que la mise à jour() ?

Comme un moyen d'éviter NonUniqueObjectException, oui. Je pense que ça explique pourquoi JPA ne permet pas une méthode de mise à jour.

Quel est l'inconvénient de l'utilisation de merge() cours de mise à jour() ?

Un proscrite utilisateur peut penser à lui a une nouvelle entité gérée. Quelque chose comme

// myEntity (passed as parameter does not become managed)
// Only the one returned by the merge operation is a managed entity
session.merge(myEntity);

// "newValue" is not commited because myEntity is not managed
myEntity.setMyProperty("newValue");

Et si votre contexte de persistance ne contient pas de votre entité, peut-être que vous ne voulez pas sélectionner avant la mise à jour de comportement par défaut. Mais elle peut être évitée

  • Ajouter une version@Version) de la colonne. 0 ou NULL version indique qu'une instance est nouveau et doit être inséré, pas de mise à jour
  • Utiliser Hibernate intercepteur
  • Si vous êtes sûr que vous voulez mettre à jour au lieu d'insérer, vous pouvez utiliser l'approche suivante

...

public void updateMyEntity(MyEntity updateableMyEntity);

    // load does not hit the database
    MyEntity myEntity = (MyEntity) session.load(MyEntity.class, updateableMyEntity.getId());

    BeanUtils.copyProperties(myEntity, updateableMyEntity);

}

De cette façon, vous pouvez mettre à jour votre entité, sans fusion ou de la méthode de mise à jour. Peut-être vous voulez voir ce Meilleure façon de mettre à jour certains champs d'un décollement de l'objet sur Hibernate ? question

en ce qui concerne,

4voto

Mark R Points 223

Utilisez update () si vous êtes sûr que la session ne contient pas d'instance déjà persistante avec le même identifiant et merge () si vous souhaitez fusionner vos modifications à tout moment sans tenir compte de l'état de la session. En d'autres termes, update () est généralement la première méthode que vous appelez dans une nouvelle session, garantissant que le rattachement de vos instances détachées est la première opération exécutée.

0voto

Ajit Deswal Points 11
SessionFactory factory = cfg.buildSessionFactory();

Session session1 = factory.openSession();
Student s1 = null;
Object o = session1.get(Student.class, new Integer(101));
s1 = (Student)o;
session1.close();
s1.setMarks(97);

Session session2 = factory.openSession();
Student s2 = null;
Object o1 = session2.get(Student.class, new Integer(101));
s2 = (Student)o1;

Transaction tx=session2.beginTransaction();
session2.merge(s1);

Explication

Voir à partir de la ligne des numéros 4 à 7, nous viens de charger un objet s1 en session1 cache et fermé session1 au numéro de la ligne 7, de sorte que maintenant l'objet s1 dans la session1 cache sera détruit comme session1 cache expire lorsque nous disons session1.close().

Maintenant s1 objet sera dans la mémoire RAM de l'emplacement, pas dans la session1 cache. Ici s1 est en état détaché, et à la ligne numéro 8 nous avons modifié qui s'est détachée de l'objet s1, maintenant, si nous appelons update() méthode, puis hibernate génère une erreur, parce que nous pouvons mettre à jour l'objet de la session seulement.

Nous avons donc ouvert une autre session [session2] à la ligne numéro 10, et encore chargés de la même étudiant objet à partir de la base de données, mais avec le nom de s2. Donc, dans ce session2, nous l'avons appelé, session2.merge(s1); maintenant en s2 objet s1 changements seront fusionnés et enregistré dans la base de données

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