Vous ne pouvez utiliser qu'un EntityGraph
si l'attribut d'association fait partie de la superclasse et par là également de toutes les sous-classes. Sinon, le EntityGraph
échouera toujours avec l'Exception
que vous obtenez actuellement.
La meilleure façon d'éviter votre problème de sélection N+1 est de diviser votre requête en 2 requêtes :
La 1ère requête récupère la MCValue
entités utilisant un EntityGraph
pour récupérer l'association mappée par le selected
attribut. Après cette requête, ces entités sont ensuite stockées dans le cache de 1er niveau d'Hibernate / le contexte de persistance. Hibernate les utilisera lorsqu'il traitera le résultat de la 2ème requête.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
La 2ème requête récupère ensuite la Answer
entity et utilise un EntityGraph
pour récupérer également la Value
associée entités. Pour chaque Value
entité, Hibernate instancie la sous-classe spécifique et vérifie si le cache de 1er niveau contient déjà un objet pour cette combinaison de classe et de clé primaire. Si c'est le cas, Hibernate utilise l'objet du cache de 1er niveau au lieu des données renvoyées par la requête.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Parce que nous avons déjà récupéré tous les MCValue
entités avec le selected
associé entités, nous obtenons maintenant Answer
entités avec une value
initialisée association. Et si l'association contient une MCValue
entité, son selected
l'association sera également initialisée.