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.