Given the following domain model, I want to load all Answer
s including their Value
s and their respective sub-children and put it in an AnswerDTO<
You can only use an EntityGraph if the association attribute is part of the superclass and by that also part of all subclasses. Otherwise, the EntityGraph
will always fail with the Exception
that you currently get.
The best way to avoid your N+1 select issue is to split your query into 2 queries:
The 1st query fetches the MCValue
entities using an EntityGraph
to fetch the association mapped by the selected
attribute. After that query, these entities are then stored in Hibernate's 1st level cache / the persistence context. Hibernate will use them when it processes the result of the 2nd query.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List findAll();
The 2nd query then fetches the Answer
entity and uses an EntityGraph
to also fetch the associated Value
entities. For each Value
entity, Hibernate will instantiate the specific subclass and check if the 1st level cache already contains an object for that class and primary key combination. If that's the case, Hibernate uses the object from the 1st level cache instead of the data returned by the query.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List findAll();
Because we already fetched all MCValue
entities with the associated selected
entities, we now get Answer
entities with an initialized value
association. And if the association contains an MCValue
entity, its selected
association will also be initialized.