Możesz użyć tylko EntityGraph
jeśli atrybut asocjacji jest częścią nadklasy, a przez to również częścią wszystkich podklas. W przeciwnym razie EntityGraph zawsze zakończy się niepowodzeniem z Exception które obecnie otrzymujesz.
Najlepszym sposobem uniknięcia problemu wyboru N+1 jest podzielenie zapytania na 2 zapytania:
Pierwsze zapytanie pobiera MCValue jednostki używające EntityGraph aby pobrać asocjację zmapowaną przez selected atrybut. Po tym zapytaniu te encje są następnie przechowywane w pamięci podręcznej pierwszego poziomu Hibernate / kontekście trwałości. Hibernate użyje ich podczas przetwarzania wyniku drugiego zapytania.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
Drugie zapytanie pobiera następnie Answer i używa EntityGraph aby pobrać również powiązaną Value podmioty. Dla każdej Value Hibernate utworzy instancję określonej podklasy i sprawdzi, czy pamięć podręczna pierwszego poziomu zawiera już obiekt dla tej kombinacji klasy i klucza podstawowego. W takim przypadku Hibernate używa obiektu z pamięci podręcznej pierwszego poziomu zamiast danych zwróconych przez zapytanie.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Ponieważ pobraliśmy już wszystkie MCValue encje z powiązanym selected encje, teraz otrzymujemy Answer encje z zainicjowaną value stowarzyszenie. A jeśli powiązanie zawiera MCValue podmiot, jego selected powiązanie zostanie również zainicjowane.