PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

L'héritage JPA @EntityGraph inclut des associations facultatives de sous-classes

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.