6

NHibernate 3.1 では、ISession.SaveOrUpdateCopy()非推奨としてマークされています。ドキュメントでは、Merge()代わりに使用することを提案しています。それぞれのドキュメントは次のとおりです。

SaveOrUpdateCopy(object obj)

指定されたオブジェクトの状態を、同じ識別子を持つ永続オブジェクトにコピーします。セッションに現在関連付けられている永続インスタンスがない場合は、ロードされます。永続インスタンスを返します。指定されたインスタンスが保存されていないか、データベースに存在しない場合は、保存して、新しい永続インスタンスとして返します。それ以外の場合、指定されたインスタンスはセッションに関連付けられません。

Merge(object obj)

指定されたオブジェクトの状態を、同じ識別子を持つ永続オブジェクトにコピーします。セッションに現在関連付けられている永続インスタンスがない場合は、ロードされます。永続インスタンスを返します。指定されたインスタンスが保存されていない場合は、のコピーを保存し、それを新しい永続インスタンスとして返します。指定されたインスタンスはセッションに関連付けられません。関連付けが でマップされている場合、この操作は関連付けられたインスタンスにカスケードされcascade="merge"ます。
このメソッドのセマンティクスは、JSR-220 で定義されています。

それらは私とほとんど同じように見えますが、いくつかの微妙な点が含まれているに違いありません. もしそうなら、それらは何ですか?

4

1 に答える 1

10

SaveOrUpdateCopyは廃止されたと見なされるようになったため、 Mergeがそれを引き継ぐことを目的としています(したがって、その極端な類似性)。

これらのカスケードオプションがSaveOrUpdateCopyで利用可能であったとは思わないことを除いて、それらはほとんど同じです。ただし、Mergeは使用する方法であるため、その点は重要ではありません。


更新:NHibernateのソースコードにアクセスして、思っていたものと同じであることを確認しました。これが私が見つけたものです。

MergeSaveOrUpdateCopyの両方に非常によく似た実装があります。

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));
    }
}

それらのFireXXXXメソッドも非常に似ています。

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;
    }
}

メソッドは、異なるイベントリスナーリストを使用することを除いてまったく同じですが、リストのタイプ(IMergeEventListener)も同じです。

リスナーリストを見ると、どちらもデフォルトのリスナーで初期化されています。マージリッスンハンドラーのデフォルトリスナーはDefaultMergeEventListenerタイプで、SaveOrUpdateCopyDefaultSaveOrUpdateCopyEventListenerです。したがって、これらの違いは、これら2つの実装の違いにすぎません(つまり、デフォルトのリスナー(99%の時間)を維持する場合)。

ただし、実際に興味深いは、実装の違いです。DefaultSaveOrUpdateCopyEventListenerを見ると、次のようになります。

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

つまり、 MergeSaveOrUpdateCopyのデフォルトの動作は、カスケードアクションのみが異なり、他のすべてはまったく同じです。

于 2011-08-04T17:29:32.573 に答える