Quelle est la différence entre persist () et merge () dans Hibernate?

Quelle est la différence entre persist () et merge () dans Hibernate?

persist() peut créer une requête UPDATE & INSERT, par exemple:

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); A a=new A(); session.persist(a); a.setName("Mario"); session.flush(); 

dans ce cas, la requête sera générée comme ceci:

 Hibernate: insert into A (NAME, ID) values (?, ?) Hibernate: update A set NAME=? where ID=? 

Ainsi, la méthode persist() peut générer une insertion et une mise à jour.

Maintenant avec merge() :

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); Singer singer = new Singer(); singer.setName("Luciano Pavarotti"); session.merge(singer); session.flush(); 

C’est ce que je vois dans la firebase database:

 SINGER_ID SINGER_NAME 1 Ricky Martin 2 Madonna 3 Elvis Presley 4 Luciano Pavarotti 

Maintenant, mettez à jour un enregistrement en utilisant merge()

 SessionFactory sef = cfg.buildSessionFactory(); Session session = sef.openSession(); Singer singer = new Singer(); singer.setId(2); singer.setName("Luciano Pavarotti"); session.merge(singer); session.flush(); 

C’est ce que je vois dans la firebase database:

 SINGER_ID SINGER_NAME 1 Ricky Martin 2 Luciano Pavarotti 3 Elvis Presley 

La spécification JPA contient une description très précise de la sémantique de ces opérations, mieux que dans javadoc:

La sémantique de l’opération persist , appliquée à une entité X, est la suivante:

  • Si X est une nouvelle entité, elle devient gérée. L’entité X sera entrée dans la firebase database à ou avant la validation de la transaction ou à la suite de l’opération de vidage.

  • Si X est une entité gérée préexistante, elle est ignorée par l’opération persistante. Cependant, l’opération persist est exécutée en cascade sur les entités référencées par X, si les relations entre X et ces autres entités sont annotées avec la valeur cascade=PERSIST ou cascade=ALL ou spécifiées avec l’élément descripteur XML équivalent.

  • Si X est une entité supprimée, elle devient gérée.

  • Si X est un object détaché, l’ EntityExistsException peut être levée lorsque l’opération persistante est appelée ou que l’ EntityExistsException ou une autre PersistenceException peut être lancée à l’ EntityExistsException ou de validation.

  • Pour toutes les entités Y référencées par une relation de X, si la relation avec Y a été annotée avec la valeur de l’élément en cascade=PERSIST ou cascade=ALL , l’opération de persistance est appliquée à Y.


La sémantique de l’opération de fusion appliquée à une entité X est la suivante:

  • Si X est une entité détachée, l’état de X est copié sur une instance d’entité gérée préexistante X ‘de la même identité ou une nouvelle copie gérée X’ de X est créée.

  • Si X est une nouvelle instance d’entité, une nouvelle instance d’entité gérée X ‘est créée et l’état de X est copié dans la nouvelle instance d’entité gérée X’.

  • Si X est une instance d’entité supprimée, une IllegalArgumentException sera lancée par l’opération de fusion (ou la validation de la transaction échouera).

  • Si X est une entité gérée, elle est ignorée par l’opération de fusion. Cependant, l’opération de fusion est mise en cascade sur les entités référencées par X si ces relations ont été annotées avec la cascade=MERGE ou cascade=ALL .

  • Pour toutes les entités Y référencées par des relations de X ayant la valeur de l’élément en cascade=MERGE ou cascade=ALL , Y est fusionné de manière récursive en tant que Y ‘. Pour tous les Y référencés par X, X ‘est défini sur Y’. (Notez que si X est géré, alors X est le même object que X ‘).

  • Si X est une entité fusionnée à X ‘, avec une référence à une autre entité Y, où cascade=MERGE ou cascade=ALL n’est pas spécifié, alors la navigation de la même association à partir de X renvoie une référence à un object géré Y avec même identité persistante que Y.

Cela vient de JPA. De manière très simple:

persist (entity) doit être utilisé avec des entités totalement nouvelles, pour les append à DB (si l’entité existe déjà dans DB, il y aura EntityExistsException throw).

merge (entity) doit être utilisé pour remettre l’entité dans le contexte de persistance si l’entité a été détachée et a été modifiée.

La persistance ne devrait être appelée que sur de nouvelles entités, tandis que la fusion est destinée à rattacher des entités séparées.

Si vous utilisez le générateur assigné, l’ utilisation de la fusion au lieu de persistante peut entraîner une instruction SQL redondante , affectant ainsi les performances.

De même, l’ appel à la fusion pour les entités gérées est également une erreur puisque les entités gérées sont automatiquement gérées par Hibernate et que leur état est synchronisé avec l’enregistrement de firebase database par le mécanisme de vérification sale .