Brian Reindel Brian Reindel - 7 months ago 60
Java Question

Having an issue with org.hibernate.SessionException: Session is closed! in Hibernate

I've done quite a bit a research on this with no luck, but all the answers have a tendency to point toward the session context settings in the config file. What is odd is that I get a session connection the very first time I hit the page (and therefore, a successful result set), but then when I reload I get the following exception: org.hibernate.SessionException: Session is closed!

Here are my config settings that are not DB connection string related:

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


Here is an example of a call I make that produces the situation I described above.

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


The session variable reference is to a static field that contains the current session. All of the session connection details are textbook reference manual. For example, here is my Hibernate session utility:

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

Answer

When you get a Session with sessionFactory.getCurrentSession(), the Session is flushed and closed automatically when the transaction is commited (see Sessions and transactions for more details on this). So, here I suspect that 1. you get the Session once for all (this would explain why the first call works and why subsequent calls fail) which is wrong and 2. you seem to use the session-per-operation anti-pattern which is even worse.

In a web application, you should use a session-per-request strategy which means that "a single Session and a single database transaction implement the processing of a particular request event". Again, refer to the Sessions and transactions document.

And if you want to remove transaction demarcation from your data access code, then you could use an interceptor to start a database transaction at the begin of each request and commit it at the end of the request. Have a look at the Open Session in View for an implementation of this pattern (with a sample DAO demonstrating the benefits).

Comments