2014-09-07 13 views
13

Attualmente sto lavorando a un'applicazione che utilizza Spring Boot e Spring Data (le sue interfacce JpaRepository per la precisione) insieme a Hibernate.Spring Boot & Spring Data: come sono gestite le Hibernate Sessions?

Una cosa che adoro di Hiberante è la sua funzione di caching: quando invii più query che corrispondono a un particolare oggetto, recupererai la stessa istanza di quell'oggetto su ogni esecuzione di query (rispetto all'operatore == di Java). Tuttavia, quando si usano le Spring Data e le classi JpaRepository, questo non sembra essere sempre il caso. Per questo motivo, presumo che ci siano più istanze HibernateSession qui al lavoro.

La mia domanda è quindi: in che modo Spring Data gestisce Hibernate Sessions? Quando li apre o li chiude? C'è un modo per configurarlo per utilizzare la stessa sessione per l'intero runtime della mia applicazione per sfruttare appieno la cache degli oggetti di Hibernate? C'è un motivo non per farlo in quel modo?

Grazie,

Alan

risposta

19

credo di aver trovato la risposta me stesso. Se qualcuno trova questa domanda, ecco la mia risposta.

Come gestisce Spring Sessions Hibernate?

Quando si chiama un metodo JpaRepository (o in generale qualsiasi metodo Repository), Primavera sarà:

  • Chiedere al SessionFactory per creare una nuova sessione
  • Apri questa sessione
  • Eseguire la chiamata Repository metodo
  • Chiudi sessione

La stessa cosa sembra essere valida per qualsiasi metodo annotato con l'annotazione Spring @Transactional.

Quali sono le conseguenze?

Come programmatore ...

  • non c'è bisogno di preoccuparti di operazioni o le sessioni a tutti.
  • non è possibile fare affidamento sulla funzionalità di memorizzazione nella cache di Hibernate. Funziona solo all'interno dello stesso HibernateSession.
  • è necessario decidere l'equivalenza degli oggetti @Entity in base al loro valore di ID di ibernazione, anziché utilizzando l'operatore Java ==.
  • è necessario fare in modo che le collezioni pigri (per esempio in un riferimento @OneToMany) nelle @Entity classi (vedi FetchMode.LAZY al contrario di FetchMode.EAGER) sono utilizzati esclusivamente all'interno di un metodo @Transactional -annotated

anche per riferimento, il seguente link è stato abbastanza utile: Multiple Transactions in single session

Come per molti altri aspetti di Spring, c'è molto da guadagnare qui, se si è disposti a sacrificare il controllo diretto sulla propria applicazione.

+4

Beh, in realtà non è vero ... A seconda della demarcazione della transazione, riutilizzerai la sessione già aperta. Se hai un metodo di servizio annotato con '@ Transactional' (e hai impostato correttamente il supporto tx) spring aprirà un' Session'/'EntityManager' e lo riutilizzerà per tutte le chiamate db che fai all'interno di quella transazione. Inoltre, si dovrebbe notare che il livello di servizio dovrebbe essere il livello transazionale NON il livello di accesso ai dati. –

+0

Grazie per i chiarimenti. Questo è buono a sapersi. – Alan47

Problemi correlati