Hibernate openSession () vs getCurrentSession ()


130

Ho alcune domande sull'uso di Hibernate nell'applicazione Web JSP.

  1. Quale dovrebbe essere il valore per hibernate.current_session_context_class?

  2. Quindi, quale delle seguenti affermazioni dovrebbe essere utilizzata? E perché?

     Session s = HibernateUtil.getSessionFactory().openSession();
     Session s = HibernateUtil.getSessionFactory().getCurrentSession()
  3. Infine, quale è meglio "una sessione per app Web" o "una sessione per richiesta"?

Risposte:


145

Come spiegato in questo post del forum , 1 e 2 sono correlati. Se si imposta hibernate.current_session_context_classsu thread e quindi si implementa qualcosa di simile a un filtro servlet che apre la sessione, è possibile accedere a quella sessione in qualsiasi altro luogo utilizzando il SessionFactory.getCurrentSession().

SessionFactory.openSession()apre sempre una nuova sessione che è necessario chiudere al termine delle operazioni. SessionFactory.getCurrentSession()restituisce una sessione associata a un contesto: non è necessario chiuderla.

Se si utilizzano Spring o EJB per gestire le transazioni, è possibile configurarle per aprire / chiudere sessioni insieme alle transazioni.

Non dovresti mai usare one session per web app- la sessione non è un oggetto thread-safe - non può essere condivisa da più thread. Devi sempre utilizzare "una sessione per richiesta" o "una sessione per transazione"


Grazie mille, @gkamal. Guardo il codice in Open Session in Visualizza documento. (Il tuo link punta a quei documenti.) L'autore suggerisce l'uso del filtro. Nel suo codice filtro, non chiama openSession()o close(). Lui chiama solo getCurrentSession(). Credo che si mette current_session_contexta thread. Ora penso di aver capito getCurrentSession(). Tuttavia, non so quando dovrei usare openSession().
Wannik,

4
Utilizzerai OpenSession se non vuoi che la sessione sia associata a nessun contesto. Ci sono alcune situazioni in cui avresti bisogno di una sessione diversa - diversa da una legata al contesto (gli Hibernate Interceptor hanno una limitazione che non puoi usare la sessione originale) - in quei casi useresti OpenSession invece di currentSession. OpenSession crea una nuova sessione che devi chiudere esplicitamente. Ad esempio, in un metodo DAO chiamerai OpenSession: usa la sessione e chiudila.
gkamal

sto usando getCurrentSession (); perché l'ho inizializzato in listener non filtra è ok dalla tua vista; sto usando mvc2 jsp servlet
shareef

@gkamal - Ho una domanda relativa a Sessions. Potete per favore aiutarmi con questo su - stackoverflow.com/questions/23351083/… . Grazie e chenqui.
Erran Morad,

IMO, è buona prassi lasciare che ogni thread mantenga la propria sessione e solo una sessione, giusto?
coderz,

31

Se parliamo di SessionFactory.openSession ()

  • Crea sempre un nuovo oggetto Session.
  • È necessario svuotare e chiudere esplicitamente gli oggetti sessione.
  • In un ambiente a thread singolo è più lento di getCurrentSession ().
  • Non è necessario configurare alcuna proprietà per chiamare questo metodo.

E se parliamo di SessionFactory.getCurrentSession ()

  • Crea una nuova sessione se non esiste, altrimenti utilizza la stessa sessione che si trova nel contesto di ibernazione corrente.
  • Non è necessario svuotare e chiudere gli oggetti sessione, verrà automaticamente curato da Hibernate internamente.
  • In un ambiente a thread singolo è più veloce di openSession ().
  • Devi configurare proprietà aggiuntive. "hibernate.current_session_context_class" per chiamare il metodo getCurrentSession (), altrimenti genererà un'eccezione.

La risposta sopra dice di non usare una singola sessione per webapp. Quindi se dovessi usare getCurrentSession, riutilizzerebbe la stessa sesssion, no?
parsecer,

9

openSession: Quando chiami SessionFactory.openSession, crea sempre un nuovo Sessionoggetto e te lo regala.

È necessario svuotare e chiudere esplicitamente questi oggetti sessione.

Poiché gli oggetti sessione non sono thread-safe, è necessario creare un oggetto sessione per richiesta in un ambiente multi-thread e una sessione per richiesta anche nelle applicazioni Web.

getCurrentSession: Quando chiami SessionFactory.getCurrentSession, ti fornirà l'oggetto sessione che si trova in un contesto di ibernazione e gestito internamente da ibernazione. È vincolato all'ambito della transazione.

Quando chiami SessionFactory.getCurrentSession, crea un nuovoSession se non esiste, altrimenti usa la stessa sessione che si trova nel contesto di ibernazione corrente. Svuota e chiude automaticamente la sessione al termine della transazione, quindi non è necessario eseguirla esternamente.

Se si utilizza l'ibernazione in un ambiente a thread singolo, è possibile utilizzare getCurrentSession, poiché è più veloce nelle prestazioni rispetto alla creazione di una nuova sessione ogni volta.

Per utilizzare il metodo è necessario aggiungere la seguente proprietà a hibernate.cfg.xmlgetCurrentSession :

<session-factory>
    <!--  Put other elements here -->
    <property name="hibernate.current_session_context_class">
          thread
    </property>
</session-factory>

Un servlet non apre un nuovo thread per ogni richiesta? Quindi se è una webapp Java, non è già un ambiente a thread singolo?
parsecer

0
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Parameter            |                                openSession                                 |                                          getCurrentSession                                          |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session  creation    | Always open new session                                                    | It opens a new Session if not exists , else use same session which is in current hibernate context. |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Session close        | Need to close the session object once all the database operations are done | No need to close the session. Once the session factory is closed, this session object is closed.    |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Flush and close      | Need to explicity flush and close session objects                          | No need to flush and close sessions , since it is automatically taken by hibernate internally.      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Performance          | In single threaded environment , it is slower than getCurrentSession       | In single threaded environment , it is faster than openSession                                      |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| Configuration        | No need to configure any property to call this method                      | Need to configure additional property:                                                              |
|                      |                                                                            |  <property name=""hibernate.current_session_context_class"">thread</property>                       |
+----------------------+----------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+

-6

SessionFactory: "Una SessionFactory per applicazione per DataBase" (ad esempio, se si utilizzano 3 DataBase nella nostra applicazione, è necessario creare un oggetto sessionFactory per ciascun DB, in totale è necessario creare 3 sessionFactorys. Oppure se si dispone di un solo DataBase One sessionfactory è abbastanza ).

Sessione: "Una sessione per un ciclo di richiesta-risposta". puoi aprire la sessione quando arriva la richiesta e puoi chiudere la sessione dopo il completamento del processo di richiesta. Nota: -Non utilizzare una sessione per l'applicazione Web.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.