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
関連付けも初期化されます。