88

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

両者の違いを説明してください。

4

6 に答える 6

160

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

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

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

そして、merge() は大きく異なります。

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

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

于 2008-10-04T21:20:09.290 に答える
9

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

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

于 2008-10-04T21:23:14.023 に答える
4

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

于 2011-04-05T11:38:37.747 に答える
1

このタイプの例外を説明するかなり良い仕事をしたこのリンクを見つけました:

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

  1. マッピング Myclass.hbm.xml ファイルで、次のように設定します。cascade="merge"
  2. SaveOrUpdate親オブジェクトに割り当てる前に、最初に子/従属オブジェクトを割り当てます。
  3. SaveOrUpdate親オブジェクト。

ただし、このソリューションには制限があります。つまり、hibernate に任せるのではなく、子/従属オブジェクトの保存に注意する必要があります。

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

于 2014-02-17T21:23:55.913 に答える