Puoi utilizzare solo un EntityGraph
se l'attributo di associazione fa parte della superclasse e quindi anche di tutte le sottoclassi. Altrimenti, il EntityGraph
fallirà sempre con l'Exception
che attualmente ottieni.
Il modo migliore per evitare il tuo problema di selezione N+1 è dividere la tua query in 2 query:
La prima query recupera il MCValue
entità che utilizzano un EntityGraph
per recuperare l'associazione mappata dal selected
attributo. Dopo quella query, queste entità vengono quindi archiviate nella cache di primo livello di Hibernate / nel contesto di persistenza. Hibernate li utilizzerà quando elabora il risultato della seconda query.
@Query("SELECT m FROM MCValue m") // add WHERE clause as needed ...
@EntityGraph(attributePaths = {"selected"})
public List<MCValue> findAll();
La seconda query recupera quindi la Answer
entità e utilizza un EntityGraph
per recuperare anche il Value
associato entità. Per ogni Value
entità, Hibernate istanzia la sottoclasse specifica e controlla se la cache di 1° livello contiene già un oggetto per quella classe e combinazione di chiavi primarie. In tal caso, Hibernate utilizza l'oggetto dalla cache di 1° livello invece dei dati restituiti dalla query.
@Query("SELECT a FROM Answer a")
@EntityGraph(attributePaths = {"value"})
public List<Answer> findAll();
Perché abbiamo già recuperato tutti i MCValue
entità con il selected
associato entità, ora otteniamo Answer
entità con un value
inizializzato associazione. E se l'associazione contiene un MCValue
entità, è selected
verrà inizializzata anche l'associazione.