PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

L'ereditarietà JPA @EntityGraph include associazioni facoltative di sottoclassi

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.