Solo puede usar un EntityGraph
si el atributo de asociación es parte de la superclase y por eso también parte de todas las subclases. De lo contrario, el EntityGraph
siempre fallará con la Exception
que recibe actualmente.
La mejor manera de evitar su problema de selección N+1 es dividir su consulta en 2 consultas:
La primera consulta obtiene el MCValue
entidades usando un EntityGraph
para obtener la asociación mapeada por el selected
atributo. Después de esa consulta, estas entidades se almacenan en el caché de primer nivel de Hibernate/el contexto de persistencia. Hibernate los usará cuando procese el resultado de la segunda consulta.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
La segunda consulta obtiene la Answer
entidad y usa un EntityGraph
para obtener también el Value
asociado entidades. Para cada Value
entidad, Hibernate creará una instancia de la subclase específica y verificará si el caché de primer nivel ya contiene un objeto para esa clase y combinación de clave principal. Si ese es el caso, Hibernate usa el objeto del caché de primer nivel en lugar de los datos devueltos por la consulta.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Porque ya recuperamos todos los MCValue
entidades con el asociado selected
entidades, ahora obtenemos Answer
entidades con un value
inicializado asociación. Y si la asociación contiene un MCValue
entidad, su selected
la asociación también se inicializará.