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 requête sera généré comme ceci:
Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?
alors 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();
Voici ce que je vois dans la base de données:
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();
Voici ce que je vois dans la base de données:
SINGER_ID SINGER_NAME
1 Ricky Martin
2 Luciano Pavarotti
3 Elvis Presley
spécification JPA contient une description très précise de la sémantique de ces opérations, meilleure 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 base de données au plus tard à 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 de persistance. Cependant, l'opération persist est mise en cascade vers les entités référencées par X, si les relations de X avec ces autres entités sont annotées avec le signe
cascade=PERSIST
oucascade=ALL
valeur d'élément d'annotation ou spécifiée avec l'élément de descripteur XML équivalent.Si X est une entité supprimée, elle devient gérée.
Si X est un objet détaché, le
EntityExistsException
peut être levé lorsque l'opération de persistance est appelée ou leEntityExistsException
ou un autrePersistenceException
peut être levé au moment de la purge ou de la validation.Pour toutes les entités Y référencées par une relation de X, si la relation à Y a été annotée avec la valeur de l'élément en cascade
cascade=PERSIST
oucascade=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, un
IllegalArgumentException
sera émis 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. Toutefois, l'opération de fusion est mise en cascade vers les entités référencées par les relations à partir de X si ces relations ont été annotées avec la valeur de l'élément en cascade
cascade=MERGE
oucascade=ALL
annotation.Pour toutes les entités, Y est référencé par des relations à partir de X ayant la valeur de l'élément en cascade
cascade=MERGE
oucascade=ALL
, Y est fusionné de manière récursive en tant que Y '. Pour tous ces Y référencés par X, X 'est défini pour référencer Y'. (Notez que si X est géré, X est le même objet que X '.)Si X est une entité fusionnée avec X ', avec une référence à une autre entité Y, où
cascade=MERGE
oucascade=ALL
n'est pas spécifié, la navigation de la même association à partir de X 'renvoie une référence à un objet géré Y' avec la même identité persistante que Y.
Cela vient de JPA. De manière très simple:
persist (entité) doit être utilisé avec des entités totalement nouvelles, pour les ajouter à la base de données (si l'entité existe déjà dans la base de données, il y aura une entité EntityExistsException).
fusionner (entité) doit être utilisé pour remettre l'entité en contexte de persistance si l'entité a été détachée et modifiée.
La persistance doit être appelée uniquement sur les nouvelles entités, alors que la fusion est destinée à rattacher les entités détachées.
Si vous utilisez le générateur affecté, tiliser la fusion au lieu de persist peut provoquer une instruction SQL redondante , affectant ainsi les performances.
En outre, fusion d'appel pour les entités gérées est également une erreur, car les entités gérées sont automatiquement gérées par Hibernate et leur état est synchronisé avec l'enregistrement de la base de données par le mécanisme de vérification à blanc après - effacement du contexte de persistance .
la différence la plus importante est la suivante: En cas d'utilisation de la méthode persist, si l'entité à gérer dans le contexte de persistance existe déjà dans le contexte de persistance, la nouvelle est ignorée. (RIEN ne s'est passé) Mais en cas de méthode de fusion, l'entité déjà gérée dans un contexte de persistance sera remplacée par la nouvelle entité (mise à jour) et une copie de cette entité mise à jour sera renvoyée. (à partir de maintenant, toute modification doit être apportée à cette entité renvoyée si vous souhaitez refléter vos modifications dans le contexte de persistance)