web-dev-qa-db-ja.com

session.Mergeとsession.SaveOrUpdateの違いは何ですか?

親/子オブジェクトまたは多対多の関係で時々気づくので、SaveOrUpdateまたはMergeを呼び出す必要があります。通常、SaveOrUpdateを呼び出す必要がある場合、Mergeの呼び出しで発生する例外は、最初に保存されていない一時オブジェクトに関係しています。

2つの違いを説明してください。

86
EvilSyn

これは、Hibernateリファレンスドキュメントのセクション 10.7。自動状態検出 からのものです。

saveOrUpdate()は次のことを行います。

  • オブジェクトがこのセッションですでに永続的である場合、何もしません
  • セッションに関連付けられた別のオブジェクトが同じ識別子を持つ場合、例外をスローします
  • オブジェクトに識別子プロパティがない場合、save()
  • オブジェクトの識別子に、新しくインスタンス化されたオブジェクトに割り当てられた値がある場合、save()
  • オブジェクトが(<version>または<timestamp>によって)バージョン管理され、バージョンプロパティ値が新しくインスタンス化されたオブジェクトに割り当てられた値と同じ場合、save()
  • それ以外の場合、オブジェクトをupdate()

そして、merge()は非常に異なります:

  • 現在セッションに関連付けられている同じ識別子を持つ永続インスタンスがある場合、指定されたオブジェクトの状態を永続インスタンスにコピーします
  • セッションに現在関連付けられている永続インスタンスがない場合は、データベースからロードするか、新しい永続インスタンスを作成してください
  • 永続インスタンスが返されます
  • 指定されたインスタンスはセッションに関連付けられず、切り離されたままになります

セッションから一時的に切り離されたオブジェクトを更新する場合、特に現在セッションに関連付けられているオブジェクトの永続インスタンスがある場合は、Merge()を使用する必要があります。そうしないと、その場合にSaveOrUpdate()を使用すると例外が発生します。

156
David Crow

私が理解しているように、merge()は現在のセッションに関連付けられていない可能性のあるオブジェクトを取得し、その状態(プロパティ値など)をのオブジェクトにコピーします現在のセッションに関連付けられているis(もちろん、同じPK値/識別子を持つ)。

saveOrUpdate()は、指定されたオブジェクトのID値に基づいて、セッションでSaveまたはpdateを呼び出します。

9
Ryan Duffield

SaveOrUpdateCopy()は、NHibernate 3.1で非推奨になりました。代わりにMerge()を使用する必要があります。

4
Ricardo Peres
** Update()**

:-セッションに同じ識別子を持つ既に永続的なインスタンスが含まれていないことが確実な場合、updateを使用してデータをhibernateに保存します

** Merge()**

:-セッションの状態を知らずにいつでも変更を保存したい場合は、hibernateでmerge()を使用します。

2
Mohit Singh

Quoc Truongの投稿にコメントしたり投票したりできないように、新しいユーザーID。ただし、前述のように、このリンクは非常に役立つと思います。

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

1
BoBoCoding

this リンクは、このタイプの例外を説明する非常に良い仕事をしました:

私のために働いたのは次のとおりです:

  1. マッピングMyclass.hbm.xmlファイルで、cascade="merge"
  2. SaveOrUpdate最初に子/依存オブジェクトを親オブジェクトに割り当てる前に。
  3. SaveOrUpdate親オブジェクト。

ただし、このソリューションには制限があります。つまり、休止状態にさせる代わりに、子/依存オブジェクトの保存に注意する必要があります。

誰かがより良い解決策を持っているなら、私は見たいです。

1
Quoc Truong