What is the difference between ISession.SaveOrUpdateCopy () and ISession.Merge ()?

In NHibernate 3.1, ISession.SaveOrUpdateCopy() marked as deprecated. The documentation suggests using Merge() . The documentation for each is as follows:

SaveOrUpdateCopy(object obj)

Copy the state of this object to a permanent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If this instance is unsaved or does not exist in the database, save it and return it as a new persistent instance. Otherwise, this instance is not associated with the session.

Merge(object obj)

Copy the state of this object to a permanent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If this instance is not saved, save the copy and return it as a newly saved example. This instance is not associated with a session. This operation cascades to related instances if the association is mapped to cascade="merge" .
The semantics of this method are defined by JSR-220.

They look almost identical to me, but there will certainly be some subtleties. If so, what are they?

+6
source share
1 answer

SaveOrUpdateCopy is now considered obsolete, and therefore Merge is designed to capture it (hence its extreme similarity).

They are almost the same, but I don’t think that these cascade options are accessible using SaveOrUpdateCopy . However, this point is controversial since the Combine method should be used.


UPDATE I went into the NHibernate source code to make sure they are the same as I thought, and this is what I found.

Both Merge and SaveOrUpdateCopy have very similar implementations:

 public object Merge(string entityName, object obj) { using (new SessionIdLoggingContext(SessionId)) { return FireMerge(new MergeEvent(entityName, obj, this)); } } public object SaveOrUpdateCopy(object obj) { using (new SessionIdLoggingContext(SessionId)) { return FireSaveOrUpdateCopy(new MergeEvent(null, obj, this)); } } 

Their FireXXXX methods are also very similar:

 private object FireMerge(MergeEvent @event) { using (new SessionIdLoggingContext(SessionId)) { CheckAndUpdateSessionStatus(); IMergeEventListener[] mergeEventListener = listeners.MergeEventListeners; for (int i = 0; i < mergeEventListener.Length; i++) { mergeEventListener[i].OnMerge(@event); } return @event.Result; } } private object FireSaveOrUpdateCopy(MergeEvent @event) { using (new SessionIdLoggingContext(SessionId)) { CheckAndUpdateSessionStatus(); IMergeEventListener[] saveOrUpdateCopyEventListener = listeners.SaveOrUpdateCopyEventListeners; for (int i = 0; i < saveOrUpdateCopyEventListener.Length; i++) { saveOrUpdateCopyEventListener[i].OnMerge(@event); } return @event.Result; } } 

The methods are exactly the same, except that they use different lists of event listeners, but even the list types ( IMergeEventListener ) are the same!

By looking at the listener lists, they are both initialized by the default listener. The default listener for Merge listeners is of type DefaultMergeEventListener , and SaveOrUpdateCopy is DefaultSaveOrUpdateCopyEventListener . So the difference between the two is just the difference in the two implementations (that is, if you keep the default listener, which is 99% of the time).

However, the real interesting fact of IS is the difference in implementation. If you look at DefaultSaveOrUpdateCopyEventListener , you will get the following:

 public class DefaultSaveOrUpdateCopyEventListener : DefaultMergeEventListener { protected override CascadingAction CascadeAction { get { return CascadingAction.SaveUpdateCopy; } } } 

This means that the default behavior for Combine and SaveOrUpdateCopy differs only in cascading actions, everything else is exactly the same.

+10
source

Source: https://habr.com/ru/post/894293/


All Articles