2010-03-07 5 views
9

Ich habe eine ganze Reihe von Nachforschungen darüber gemacht, ohne Glück, aber alle Antworten neigen dazu, auf die Sitzungskontexteinstellungen in der Konfigurationsdatei hinzuweisen. Was komisch ist, ist, dass ich eine Sitzungsverbindung bekomme, wenn ich das erste Mal auf die Seite klicke (und daher eine erfolgreiche Ergebnismenge), aber beim Nachladen bekomme ich die folgende Ausnahme: org.hibernate.SessionException: Sitzung ist geschlossen!Ein Problem mit org.hibernate.SessionException: Sitzung ist geschlossen! in Hibernate

Hier sind meine Config-Einstellungen, die nicht im Zusammenhang Verbindungszeichenfolge DB:

<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> 

Hier ein Beispiel für einen Anruf ich, dass die Situation erzeugt ich oben beschrieben.

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; 
} 

Die Sitzungs variable Referenz auf ein statisches Feld, das die aktuelle Sitzung enthält. Alle Sitzungsverbindungsdetails sind Lehrbuch-Referenzhandbuch. Zum Beispiel, hier ist mein Hibernate Session-Dienstprogramm:

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

Haben Sie eine Implementierung, um die Sitzung zu beenden/zu beenden? –

Antwort

8

Wenn Sie eine Session mit sessionFactory.getCurrentSession() bekommen, ist die Session gespült und automatisch geschlossen, wenn die Transaktion (siehe Sessions and transactions, um weitere Informationen zu diesem Thema) verpflichtet ist. Also, hier vermute ich, dass 1. Sie die Sitzung ein für allemal erhalten (dies würde erklären, warum der erste Anruf funktioniert und warum nachfolgende Anrufe fehlschlagen), was falsch ist und 2. Sie scheinen die Sitzung pro Operation zu verwenden anti- Muster, das noch schlimmer ist.

In einer Web-Anwendung, sollten Sie eine Session-per-Anfrage Strategie verwenden, was bedeutet, dass „eine einzige Session und eine einzelne Datenbanktransaktion, die Verarbeitung eines bestimmten Anforderungsereignisses implementieren“. Siehe auch das Dokument Sessions and transactions.

Und wenn Sie die Transaktionsabgrenzung von Ihrem Datenzugriffscode entfernen möchten, können Sie eine interceptor verwenden, um eine Datenbanktransaktion zu Beginn jeder Anfrage zu starten und am Ende der Anfrage zu committen. Werfen Sie einen Blick auf die Open Session in View für eine Implementierung dieses Musters (mit einem Beispiel DAO demonstrieren die Vorteile).

+0

Das Problem mit all dem ist: 1) Die Referenzdokumentation verwendet ein grundlegendes Beispiel, das sie Ihnen unmittelbar danach sagen, ist falsch für Produktionsszenarien (was viel zu wünschen übrig in Bezug auf häufige Szenarien). 2) Transaktionen sind fast immer betriebsbereit, aber die Dokumentation zeigt eine Transaktion pro Sitzung pro Anfrage. Seit wann benutzt jemand eine Transaktion für einen gesamten Anfrageumfang? Sie haben möglicherweise drei separate Transaktionen, die Sie während der Anforderung zurücksetzen müssen. Dies ist ein Bereich, in dem Hibernate mit der Dokumentation besser arbeiten muss. –

+0

Am Ende hing das Problem damit zusammen, wie ich die Sitzungsvariablenreferenz behandelte. Ich werde wahrscheinlich die Verarbeitung der offenen/schließenden Sitzung in einen Filter verschieben und dann die einzelnen Transaktionen pro Operation (oder Gruppe von Operationen) verwalten. –

+0

@ hal10001 Ich stimme nicht zu, dass Transaktionen fast immer in Betrieb sind, Sie wollen ** nicht ** die "Hälfte einer Anfrage" (die Session-pro-Operation nennt man kein Anti-Pattern für nichts), verwenden Eine Transaktion pro Anfrage ist der Weg zu gehen. –

Verwandte Themen