Можете да използвате само EntityGraph
ако атрибутът на асоцииране е част от суперкласа и по този начин също част от всички подкласове. В противен случай EntityGraph
винаги ще се провали с Exception
които получавате в момента.
Най-добрият начин да избегнете проблема с избора на N+1 е да разделите заявката си на 2 заявки:
Първата заявка извлича MCValue
обекти с помощта на EntityGraph
за извличане на асоциацията, картографирана от selected
атрибут. След тази заявка тези обекти се съхраняват в кеша от първо ниво на Hibernate / контекста на постоянство. Hibernate ще ги използва, когато обработва резултата от второто запитване.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
Втората заявка след това извлича Answer
обект и използва EntityGraph
за да извлече и свързаната Value
образувания. За всяка Value
обект, Hibernate ще създаде конкретния подклас и ще провери дали кешът от първо ниво вече съдържа обект за този клас и комбинация от първичен ключ. Ако случаят е такъв, Hibernate използва обекта от кеша от първо ниво вместо данните, върнати от заявката.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Тъй като вече извлякохме всички MCValue
обекти със съответния selected
обекти, сега получаваме Answer
обекти с инициализирана Value
асоциация. И ако асоциацията съдържа MCValue
обект, неговият selected
асоциирането също ще бъде инициализирано.