Você só pode usar um
EntityGraph
se o atributo de associação faz parte da superclasse e por isso também faz parte de todas as subclasses. Caso contrário, o EntityGraph
sempre falhará com a Exception
que você recebe atualmente. A melhor maneira de evitar o problema de seleção N+1 é dividir sua consulta em 2 consultas:
A primeira consulta busca o
MCValue
entidades usando um EntityGraph
para buscar a associação mapeada pelo selected
atributo. Após essa consulta, essas entidades são armazenadas no cache de 1º nível do Hibernate / o contexto de persistência. O Hibernate irá usá-los quando processar o resultado da 2ª consulta. @Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
A segunda consulta então busca a
Answer
entidade e usa um EntityGraph
para também buscar o Value
associado entidades. Para cada Value
entidade, o Hibernate irá instanciar a subclasse específica e verificar se o cache de 1º nível já contém um objeto para aquela classe e combinação de chave primária. Se for o caso, o Hibernate usa o objeto do cache de 1º nível ao invés dos dados retornados pela consulta. @Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Porque já buscamos todos os
MCValue
entidades com o selected
associado entidades, agora temos Answer
entidades com um value
inicializado Associação. E se a associação contiver um MCValue
entidade, seu selected
associação também será inicializada.