Je kunt alleen een EntityGraph
als het associatieattribuut deel uitmaakt van de superklasse en daarmee ook deel uitmaakt van alle subklassen. Anders wordt de EntityGraph zal altijd mislukken met de Exception die je momenteel krijgt.
De beste manier om uw N+1 select-probleem te voorkomen, is door uw zoekopdracht in 2 zoekopdrachten te splitsen:
De eerste zoekopdracht haalt de MCValue entiteiten met behulp van een EntityGraph om de associatie op te halen die is toegewezen door de selected attribuut. Na die query worden deze entiteiten vervolgens opgeslagen in de cache van het eerste niveau van Hibernate / de persistentiecontext. Hibernate zal ze gebruiken wanneer het het resultaat van de tweede zoekopdracht verwerkt.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
De 2e vraag haalt dan het Answer . op entiteit en gebruikt een EntityGraph om ook de bijbehorende Value op te halen entiteiten. Voor elke Value entiteit, zal Hibernate de specifieke subklasse instantiëren en controleren of de cache van het 1e niveau al een object bevat voor die combinatie van klasse en primaire sleutel. Als dat het geval is, gebruikt Hibernate het object uit de cache van het eerste niveau in plaats van de gegevens die door de query worden geretourneerd.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Omdat we al alle MCValue . hebben opgehaald entiteiten met de bijbehorende selected entiteiten, krijgen we nu Answer entiteiten met een geïnitialiseerde value vereniging. En als de associatie een MCValue . bevat entiteit, de selected koppeling wordt ook geïnitialiseerd.