Spring と Hibernate を一緒に使用する方法を概説した ProSpring 3 の本を読んでいました。しかし、「アソシエーションを熱心に取得できます」という記述に出くわしました。私の質問は:
Hibernate でアソシエーションを積極的にフェッチすることは、実際には何を意味し、Hibernate でのクエリのパフォーマンスにどのように影響しますか?
Eager fetching とは、親エンティティがデータベースから検索されるときに、関連付けられているすべてのエンティティが同時に検索されることを意味します。
遅延フェッチ (逆) は、親エンティティ自身のフィールドのみが検索されることを意味します。関連付けられたエンティティには、参照された場合にデータベースからそれらを検索するプロキシが設定されます。
そのため、クエリ パフォーマンスの主な違いは、関連付けられたエンティティの検索がいつ行われるかという点にあります。熱心なフェッチでは、これは常に親がロードされると同時に発生しますが、遅延フェッチでは、これは後で発生します (おそらく決して発生しません)。
遅延読み込みは、オンデマンドの動作のため明らかに勝者のように思えますが、注意すべき点がいくつかあります。まず、接続の範囲を確認するのが非常に難しい場合があります。通常のエンティティ オブジェクトのように見えるものには、実際にはデータベース接続が埋め込まれており、「通常の」getter メソッド (またはさらに悪いことに、これらのメソッドのクライアント) によっていつでも呼び出すことができます。いつ接続を閉じたり、プールに戻したりできるかを知ることは、ほとんど不可能です。同様に、この動作は、デバッグ中に「単純な」オブジェクトにフィールドが設定されていない場合や、「単純な」オブジェクトの getter メソッドから返されたコレクションを反復処理している場合に SQL 例外をスローする場合に混乱を引き起こす可能性があります。
さらに、関連付けられたエンティティが親エンティティとは別に読み込まれると、集計パフォーマンスが低下する可能性があります。別の SQL ラウンドトリップの余分なオーバーヘッドがありますが、さらに重要なことは、データベースが結合などで既存のルックアップを再利用できないことです。
私見(そして経験から言えば)、関係が使用されない可能性が高い場合、遅延読み込みは慎重に検討された最適化である必要があります。