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.