web-dev-qa-db-ja.com

ORM:ランタイムプロキシとバイトコードインストルメンテーション

バイトコードのインストルメンテーション/拡張と比較して、HibernateやEclipseLinkなどのORMプロバイダーでランタイムプロキシを使用する利点は何ですか?

バイトコードのインストルメンテーションがダーティチェックの最適化に役立つことを知っています。変更をインターセプトできるので、ORMプロバイダーは永続コンテキスト内のすべてのオブジェクトをトラバースし、現在の値をオブジェクトのロード時に取得されたスナップショットと比較する必要はありません(したがって、追加のメモリ消費も回避すると思います)。

また、ORMプロバイダーは、プロキシを作成する必要があるかどうか、またはプロキシの主キー値が何であるかがわからないため、追加のクエリを実行する必要がある場合にも役立ちます レイジー1対1 アソシエーション。したがって、アソシエーションは状況によっては効果的に熱心になります。

他のいくつかのプロキシの落とし穴がこれに説明されています blog 、(equalsおよびhashCodeメソッドでの)直接フィールドアクセスやinstanceof演算子の使用など。

バイトコードのインストルメンテーションがより良い代替手段であるように私には思えます。ランタイムプロキシアプローチと比較して、独自の落とし穴はありますか?どちらか一方を選択するときに従うべき経験則はありますか?

7

HibernateとEclipseLinkはどちらも、プロキシ設計パターンを使用して、エンティティ関係のレイジー/イーガーロードを実装します。プロキシはweaved into Javaビルド時(静的)または実行時(動的)にバイトコード-基本的にエンティティPOJOを強化します。ダーティチェックなどの他の機能もバイトコードに織り込みました。

これは、アスペクト指向プログラミング(AOP)のアプリケーションです。すべての同じ落とし穴(たとえば、実行時に予期しないクラス)と利点(たとえば、よりクリーンなソースコード、ランタイムコードインジェクション)が適用されます。

だから問題は、代替案は何ですか?ウィービングを無効にして、同じ機能(レイジーロード、ダーティチェックなど)を独自のコードに実装できます。実行時の驚きはありませんが、開発の労力が増加します。

経験則として、アノテーションを使用し、ランタイムエンティティクラスインスペクションを回避し、HibernateまたはEclipselinkコードウィービングを信頼して必要なものを提供します。複雑さが必要な場合は、独自のプロキシなどを実装するオプションが常にあることに注意してください。

3
daz