2010-03-07 12 views
9

Ho fatto un bel po 'di ricerche su questo senza fortuna, ma tutte le risposte hanno la tendenza a puntare verso le impostazioni del contesto di sessione nel file di configurazione. La cosa strana è che ottengo una connessione di sessione la prima volta che colpisco la pagina (e quindi, un set di risultati di successo), ma poi quando ricarico ottengo la seguente eccezione: org.hibernate.SessionException: la sessione è chiusa!Avere un problema con org.hibernate.SessionException: la sessione è chiusa! in Hibernate

Qui sono le mie impostazioni di configurazione che non sono dB stringa di connessione correlati:

<property name="hibernate.show_sql">false</property> 
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>   
<property name="hibernate.current_session_context_class">thread</property> 
<property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
<property name="hibernate.cache.use_query_cache">false</property> 
<property name="hibernate.cache.use_minimal_puts">false</property> 

Ecco un esempio di una chiamata che faccio che produce la situazione che ho descritto sopra.

public T get(int id) { 
    session.beginTransaction(); 
    T type; 
    try { 
     type = getTypeClass().cast(session.get(getTypeClass(), id)); 
    } catch (ClassCastException classCastException) { 
     throw new ClassCastException(classCastException.getMessage()); 
    } 
    session.getTransaction().commit(); 
    return type; 
} 

Il riferimento di variabile di sessione è un campo statico che contiene la sessione corrente. Tutti i dettagli della connessione della sessione sono manuali di riferimento. Ad esempio, ecco il mio programma di utilità Sospensione sessione:

import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 

public class HibernateSessionFactoryUtil { 

    private static final SessionFactory sessionFactory = buildSessionFactory(); 

    private static SessionFactory buildSessionFactory() { 
     try { 
      return new Configuration().configure().buildSessionFactory(); 
     } catch (Throwable ex) { 
      System.err.println("Initial SessionFactory creation failed." + ex); 
      throw new ExceptionInInitializerError(ex); 
     } 
    } 

    public static SessionFactory getSessionFactory() { 
     return sessionFactory; 
    } 
} 
+0

Avete qualche implementazione per chiudere/uccidere la sessione? –

risposta

8

Quando si ottiene una sessione con sessionFactory.getCurrentSession(), la sessione viene lavata e chiude automaticamente quando la transazione è impegnata (vedi Sessions and transactions per maggiori dettagli su questo). Quindi, qui sospetto che 1. ottieni la Sessione una volta per tutte (questo spiegherebbe perché la prima chiamata funziona e perché le successive chiamate falliscono) che è errata e 2. ti sembra di usare l'anti-session-per-operation modello che è anche peggio.

in un'applicazione Web, è necessario utilizzare un session-per-richiesta strategia che significa che "una singola sessione e una singola transazione di database implementano l'elaborazione di un particolare evento richiesta di". Ancora una volta, fare riferimento al documento Sessions and transactions.

E se si desidera rimuovere la demarcazione della transazione dal codice di accesso ai dati, è possibile utilizzare interceptor per avviare una transazione di database all'inizio di ogni richiesta e confermarla alla fine della richiesta. Dai un'occhiata allo Open Session in View per un'implementazione di questo modello (con un esempio di DAO che ne dimostra i vantaggi).

+0

Il problema con tutto questo è: 1) La documentazione di riferimento utilizza un esempio di base che immediatamente ti dicono che non è corretto per gli scenari di produzione (lasciando molto a desiderare per quanto riguarda gli scenari comuni). 2) Le transazioni sono quasi sempre operative, ma la documentazione mostra una transazione per sessione per richiesta. Da quando qualcuno usa una transazione per un intero ambito di richiesta? Potresti avere tre transazioni separate che devi eseguire il rollback durante la richiesta. Questa è un'area in cui Hibernate deve fare un lavoro migliore con la documentazione. –

+0

Alla fine il problema era legato a come gestivo il riferimento alla variabile di sessione. Probabilmente trasferirò la gestione della sessione di apertura/chiusura in un filtro e quindi gestirò le singole transazioni per operazione (o serie di operazioni). –

+0

@ hal10001 Non sono d'accordo sul fatto che le transazioni siano quasi sempre operative, tu ** non ** vuoi impegnare la "metà di una richiesta" (la sessione per operazione non è chiamata anti-pattern per niente), usando una transazione per richiesta è la strada da percorrere. –

Problemi correlati