208

Hibernate には、何らかの方法でオブジェクトを取得してデータベースに入れるメソッドがいくつかあります。それらの違いは何ですか、いつどちらを使用するか、また、いつ何を使用するかを知るインテリジェントな方法が 1 つしかないのはなぜですか?

これまでに特定した方法は次のとおりです。

  • save()
  • update()
  • saveOrUpdate()
  • saveOrUpdateCopy()
  • merge()
  • persist()
4

10 に答える 10

120

これが私の方法の理解です。これらは主にAPIに基づいていますが、実際にはこれらすべてを使用しているわけではありません。

saveOrUpdate いくつかのチェックに応じて、save または update を呼び出します。たとえば、識別子が存在しない場合、save が呼び出されます。それ以外の場合は update が呼び出されます。

save エンティティを永続化します。識別子が存在しない場合は、識別子を割り当てます。もしそうなら、それは本質的に更新を行っています。エンティティの生成された ID を返します。

update 既存の識別子を使用してエンティティを永続化しようとします。識別子が存在しない場合、例外がスローされると思います。

saveOrUpdateCopy これは非推奨であり、今後は使用しないでください。代わりに...

マージ ここで、私の知識が衰え始めます。ここで重要なことは、一時エンティティ、切り離されたエンティティ、永続エンティティの違いです。オブジェクトの状態の詳細については、こちらをご覧ください。保存と更新では、永続オブジェクトを扱います。これらはセッションにリンクされているため、Hibernate は何が変更されたかを認識します。ただし、一時的なオブジェクトがある場合、セッションは関係ありません。このような場合、更新にはマージを使用し、保存には永続化を使用する必要があります。

persist 上記のように、これは一時的なオブジェクトで使用されます。生成された ID は返しません。

于 2008-10-02T08:32:45.923 に答える
69
  • 永続化と保存の微妙な違いの説明については、 Hibernate フォーラムを参照してください。違いは、INSERT ステートメントが最終的に実行される時間のようです。saveは識別子を返すため、トランザクションの状態に関係なく、INSERT ステートメントを即座に実行する必要があります (これは一般的に悪いことです)。Persistは、識別子を割り当てるためだけに、現在実行中のトランザクション以外のステートメントを実行しません。保存/永続化は両方とも一時的なインスタンス、つまり識別子がまだ割り当てられておらず、DB に保存されていないインスタンスで機能します。

  • UpdateMergeは両方とも、切り離されたインスタンス、つまり、DB に対応するエントリがあるが、現在セッションに接続されていない (または管理されていない) インスタンスで機能します。それらの違いは、関数に渡されるインスタンスに何が起こるかです。updateはインスタンスの再アタッチを試みます。つまり、現在セッションにアタッチされている永続エンティティの他のインスタンスがあってはなりません。そうでない場合、例外がスローされます。ただし、 mergeは、すべての値をセッション内の永続インスタンスにコピーするだけです (現在ロードされていない場合はロードされます)。入力オブジェクトは変更されません。したがって、マージは更新よりも一般的です、しかしより多くのリソースを使用する可能性があります。

于 2008-10-02T09:05:00.290 に答える
5

save()実際、休止状態とメソッドの違いはpersist()、使用しているジェネレーター クラスによって異なります。

save()ジェネレータークラスが割り当てられている場合、とpersist() メソッドに違いはありません。ジェネレーターが「割り当てられた」ということは、プログラマーとして、データベースに正しく保存するための主キーの値を与える必要があるためです [このジェネレーターの概念を知っていただければ幸いです] 割り当てられたジェネレーター クラス以外の場合、ジェネレーター クラス名が Increment を意味するとしますhibernate 自体が主キー ID の値をデータベースに正しく割り当てます [割り当てられたジェネレーターを除いて、主キー ID の値を記憶するために使用される hibernate のみ]、この場合、save()またはpersist()メソッドを呼び出すと、レコードが挿入されます通常はデータベースですが、聞いたことは、 save()メソッドは休止状態によって生成された主キーID値を返すことができ、それを見ることができます

long s = session.save(k);

この同じ場合、persist()クライアントに値を返すことはありません。

于 2012-04-11T05:45:06.280 に答える
2

デタッチされたオブジェクトで更新を呼び出すと、オブジェクトを変更したかどうかに関係なく、データベースで常に更新が行われることに注意してください。それが望ましくない場合は、Session.lock() を LockMode.None と共に使用する必要があります。

オブジェクトが現在のセッションの範囲外で変更された場合にのみ、update を呼び出す必要があります (デタッチ モードの場合)。

于 2008-10-03T12:13:20.797 に答える
1

次の答えはどれも正しくありません。これらの方法はすべて似ているように見えますが、実際にはまったく異なることを行います。短いコメントをするのは難しいです。これらのメソッドに関する完全なドキュメントへのリンクを提供することをお勧めします: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html

于 2012-10-26T10:38:45.893 に答える