クラスBおよびCと1対多の関係にあるクラスAがあります。fetchTypeをEAGERに設定したため、JPAでマルチバッグフェッチの問題が発生しました。今私が知っている問題を解決する2つの方法があります。フェッチタイプを熱心に保ち、リストからセットに変更します。これは私の場合は問題ありません。または、fetchTypeを「lazy」に変更し、結合クエリを使用して関係をEAGERフェッチします。推奨されるアプローチは何ですか?
4 に答える
「JPA での複数のバッグ取得の問題」
これらは「JPA での複数のバッグ フェッチの問題」ではないことに注意してください。これは Hibernate に固有の問題です。他の JPA プロバイダーにはこの問題はなく、JPA では複数の EAGER OneToMany 関係を持つことが完全に許可されています。
積極的なコレクション フェッチでは、Hibernate はデフォルトでルート テーブルとコレクション テーブルを「クロス結合」します。これにより、重複したルート要素が返される可能性がありますが、これは望ましくない場合があります。考えられる解決策は次の 3 つです。
- 熱心にフェッチしないでください。
- FetchMode.SELECT を使用して、選択フェッチを強制します (まだ熱心ですが、結合フェッチはありません)。また
- 結果を Set にハッシュします。上記のコレクションを常に添付する必要がある場合は、セットアプローチをお勧めします。join fetch のパフォーマンスは、実質的にコストがかからない追加のハッシュ ステップを使用しても、select fetch よりも優れています。
コレクションをフェッチすることをお勧めします (ただし、hibernate を使用する場合は、クエリにも 1 回のフェッチの制限が存在します)。これは、B と C を必要とせずにすべての A オブジェクトをリストしたい場合があるためです。個人的には、主にリストを使用します。コレクションをjsfデータテーブル(セットを処理できない)に直接表示したいのですが、コレクションが複数ある場合は、コレクションをフェッチするのではなく、バックエンドで手動で読み取ってコレクションを初期化する必要があります。
コレクションをバッグではなくリストとしてマッピングすることを検討してください。これは@org.hibernate.annotations.IndexColumn
or を追加するだけで実行できます。JPA 2.0 以降では、prefer@javax.persistence.OrderColumn