EntityGraph
アソシエーション属性がスーパークラスの一部であり、それによってすべてのサブクラスの一部でもある場合。それ以外の場合、EntityGraph 常にExceptionで失敗します あなたが現在得ているもの。
N + 1選択の問題を回避する最善の方法は、クエリを2つのクエリに分割することです。
最初のクエリはMCValueをフェッチします EntityGraphを使用するエンティティ selectedによってマップされた関連付けをフェッチします 属性。そのクエリの後、これらのエンティティはHibernateの第1レベルのキャッシュ/永続コンテキストに保存されます。 Hibernateは、2番目のクエリの結果を処理するときにそれらを使用します。
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
次に、2番目のクエリがAnswerをフェッチします。 エンティティであり、EntityGraphを使用します 関連するValueもフェッチします エンティティ。 Valueごとに エンティティであるHibernateは、特定のサブクラスをインスタンス化し、第1レベルのキャッシュにそのクラスと主キーの組み合わせのオブジェクトがすでに含まれているかどうかを確認します。その場合、Hibernateは、クエリによって返されるデータの代わりに、第1レベルのキャッシュからのオブジェクトを使用します。
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
すでにすべてのMCValueをフェッチしているため 関連付けられたselectedを持つエンティティ エンティティ、Answerを取得します 初期化されたvalueを持つエンティティ 協会。また、関連付けにMCValueが含まれている場合 エンティティ、そのselected 関連付けも初期化されます。