Sie können nur einen EntityGraph
wenn das Assoziationsattribut Teil der Oberklasse und damit auch Teil aller Unterklassen ist. Ansonsten der EntityGraph
schlägt immer mit der Exception
fehl die Sie derzeit erhalten.
Der beste Weg, Ihr N+1-Auswahlproblem zu vermeiden, besteht darin, Ihre Abfrage in zwei Abfragen aufzuteilen:
Die 1. Abfrage holt den MCValue
Entitäten mit einem EntityGraph
um die Assoziation abzurufen, die durch den selected
abgebildet wird Attribut. Nach dieser Abfrage werden diese Entitäten dann im Cache der ersten Ebene von Hibernate / im Persistenzkontext gespeichert. Hibernate verwendet sie, wenn es das Ergebnis der zweiten Abfrage verarbeitet.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
Die 2. Abfrage holt dann die Answer
Entität und verwendet einen EntityGraph
um auch den zugehörigen Value
abzurufen Entitäten. Für jeden Value
-Entität, instanziiert Hibernate die spezifische Unterklasse und prüft, ob der 1st-Level-Cache bereits ein Objekt für diese Kombination aus Klasse und Primärschlüssel enthält. Wenn dies der Fall ist, verwendet Hibernate das Objekt aus dem 1st-Level-Cache anstelle der von der Abfrage zurückgegebenen Daten.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Weil wir bereits alle MCValue
abgerufen haben Entitäten mit dem zugehörigen selected
Entitäten erhalten wir jetzt Answer
Entitäten mit einem initialisierten value
Verband. Und wenn die Assoziation einen MCValue
enthält Entität, ihre selected
Association wird ebenfalls initialisiert.