web-dev-qa-db-ja.com

Hibernateはエンティティオブジェクトのダーティ状態をどのように検出しますか?

元のクラスに何らかの種類のバイトコード変更を使用していますか?

または、特定のオブジェクトを以前に永続化されたバージョンと比較することで、Hibernateがダーティステートになる可能性がありますか?

複雑なオブジェクトのhashCode()およびequals()メソッドに問題があります。オブジェクトにコレクションメンバーがある場合、ハッシュコードの計算が非常に遅くなり、循環参照も問題になると思います。

HibernateがhashCode()/equals()を使用してダーティステートをチェックしない場合、equals()/hashCode()を使用しないでくださいエンティティオブジェクト(値オブジェクトではない)ですが、同じ演算子(_==_)で十分でない場合も心配です。

したがって、質問は次のとおりです。

  1. Hibernateは、オブジェクトのプロパティが変更されたかどうかをどのように認識しますか?

  2. 複雑なオブジェクトのhashCode()/equals()メソッドをオーバーライドすることをお勧めしますか?循環参照が含まれている場合はどうなりますか?

    そしてまた、

  3. idフィールドだけでhashCode()/equals()で十分ですか?

58
Xiè Jìléi

Hibernateはinspectionと呼ばれる戦略を使用します。これは基本的にこれです。データベースからオブジェクトがロードされると、そのスナップショットがメモリに保持されます。セッションがフラッシュされると、Hibernateは保存されたスナップショットを現在の状態と比較します。それらが異なる場合、オブジェクトはダーティとしてマークされ、適切なSQLコマンドがキューに登録されます。オブジェクトがまだ一時的な場合は、常にダーティです。

出典:Hibernate in Actionを予約(付録B:ORM実装戦略)

ただし、Hibernateのダーティチェックはメソッドequals/hascodeに依存しないことに注意することが重要です。 Hibernateはこれらのメソッドをまったく調べません(Java.util.Setを使用する場合を除き、これはコレクションAPIにのみ関係するダーティチェックとは無関係です)前述の状態スナップショットは、値の配列に似たものです。このようなフレームワークの中核的な側面を開発者の手に委ねることは非常に悪い決断です(正直なところ、開発者はダーティチェックを気にするべきではありません)。言うまでもなく、equals/hascodeは、ニーズに応じてさまざまな方法で実装できます。引用された本を読むことをお勧めします。著者はequals/hascodeの実装戦略について議論しています。非常に洞察力に富んだ読書。

93
Antonio

Hibernateのデフォルトのダーティチェックメカニズム は、現在アタッチされているすべてのエンティティのすべてのマッピングプロパティを初期読み込み時の値と照合します。

次の図で、このプロセスをよりよく視覚化できます。

Default automatic dirty checking

18
Vlad Mihalcea

Hibernateは、フィールドごとのチェックを行って、エンティティの汚れを判断します。

したがって、hashCode/equalsはまったく見えません。

実際、Hibernateによって実行されるフィールドごとのダーティチェックは、パフォーマンスの点で非常にコストがかかる可能性があります。

そのため、StrategyやInterceptor.findDirty()などのインターフェイスを提供して同じものを処理します。

次の投稿でこれをより詳細に説明します(アプリケーションがoptimizeを完全にそれを実現するためのいくつかのアイデアとともに): http://prismoskills.appspot.com /lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

7
user2250246