87 votes

Quelle est la différence entre session.Merge et session.SaveOrUpdate ?

J'ai remarqué que parfois, avec mes objets parents/enfants ou mes relations plusieurs à plusieurs, je dois appeler soit SaveOrUpdate o Merge . D'habitude, quand j'ai besoin d'appeler SaveOrUpdate l'exception que je reçois en appelant Merge a à voir avec les objets transitoires qui ne sont pas sauvegardés en premier.

Veuillez expliquer la différence entre les deux.

158voto

David Crow Points 7704

Ceci est tiré de la section 10.7. Détection automatique des états de la documentation de référence d'Hibernate :

saveOrUpdate() effectue les opérations suivantes :

  • si l'objet est déjà persistant dans cette session, ne rien faire.
  • si un autre objet associé à la session a le même identifiant, lancer une exception
  • si l'objet n'a pas de propriété d'identifiant, save() le sauvera.
  • si l'identificateur de l'objet a la valeur attribuée à un nouvel objet de la catégorie instancié, sauvegarder() l'objet
  • si l'objet est versionné (par une <version> ou un <timestamp>), et l'option valeur de la propriété version est la même que celle attribuée à un objet nouvellement nouvellement instancié, save() le
  • sinon, mettez à jour() l'objet

et merge() est très différent :

  • s'il existe une instance persistante avec le même identifiant actuellement associée à la session, copier l'état de l'objet donné sur l'instance persistante l'instance persistante
  • s'il n'y a pas d'instance persistante actuellement associée à l'utilisateur. session, essayez de la charger depuis la base de données, ou créez une nouvelle instance persistante. persistante
  • l'instance persistante est retournée
  • l'instance donnée ne devient pas associée à la session, elle reste détachée

Vous devez utiliser Merge() si vous essayez de mettre à jour des objets qui ont été à un moment donné détachés de la session, en particulier si des instances persistantes de ces objets sont actuellement associées à la session. Sinon, l'utilisation de SaveOrUpdate() dans ce cas entraînerait une exception.

0 votes

Bonne réponse... Je me demande - si j'utilise la fusion sur une nouvelle entité, y a-t-il une raison d'utiliser la sauvegarde après coup ou je peux supposer que la fusion a créé la nouvelle entité dans la base de données à coup sûr ? (et s'il s'agit d'une entité détachée, une fois la fusion effectuée, les modifications sont automatiquement omises dans la base de données).

5 votes

Vous en êtes sûr ? En regardant la source NHiberante, SaveOrUpdateCopy déclenche un événement Merge avec les mêmes paramètres que la fonction Merge. Je pense qu'elles sont identiques, la fonction SaveOrUpdateCopy est quelque chose qui existe dans hibernate/nhibernate depuis la version 1.0, la fonction Merge est nouvelle et a été ajoutée à hibernate pour se conformer à un nouveau standard java (je pense).

5 votes

@Torkel - SaveOrUpdateCopy n'est pas la même chose que SaveOrUpdate . Je ne suis pas sûr que l'auteur de la question voulait comparer Merge le premier ou le second. SaveOrUpdateCopy est une méthode désormais obsolète qui effectuait une fusion dans NHibernate avant la mise en place de Merge en cours d'importation.

9voto

Ryan Duffield Points 7602

Comme je le comprends, merge() prendra un objet qui peut ne pas être associé à la session en cours, et copiera son état (valeurs des propriétés, etc.) dans un objet que l'on appelle est associé à la session actuelle (avec la même valeur PK/identifiant, bien sûr).

saveOrUpdate() appellera Sauvez o Mise à jour sur votre session, en fonction de la valeur d'identité d'un objet donné.

4voto

Ricardo Peres Points 1492

SaveOrUpdateCopy() est désormais obsolète à partir de NHibernate 3.1. Merge() doit être utilisé à la place.

9 votes

C'est SaveOrUpdateCopy qui est marqué Obsolete pas SaveOrUpdate . Il semble qu'il y ait une grande confusion entre ces deux méthodes différentes dans cette question et dans les réponses qui suivent.

1voto

BoBoCoding Points 11

Nouvel identifiant d'utilisateur, je ne peux donc pas commenter ou voter sur le message de Quoc Truong. Cependant, je pense également que le lien est très utile, comme indiqué précédemment.

http://www.roseindia.net/hibernate/hibernate4/org_hibernate_nonuniqueobjectexception.shtml

1voto

Quoc Truong Points 1

J'ai trouvé este qui explique assez bien ce type d'exception :

Ce qui a fonctionné pour moi est le suivant :

  1. Dans le fichier de mappage Myclass.hbm.xml, définissez les éléments suivants cascade="merge"
  2. SaveOrUpdate l'objet enfant/dépendant avant de l'affecter à l'objet parent.
  3. SaveOrUpdate l'objet parent.

Cependant, cette solution a des limites. Par exemple, vous devez vous occuper de sauvegarder votre objet enfant/dépendant au lieu de laisser Hibernate le faire pour vous.

Si quelqu'un a une meilleure solution, j'aimerais la voir.

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