遇到org.hibernate.SessionException问题:会话已关闭!在Hibernate中

时间:2010-03-07 23:26:26

标签: java hibernate session orm

我对此进行了相当多的研究而没有运气,但所有答案都倾向于指向配置文件中的会话上下文设置。奇怪的是,我第一次点击页面时得到了会话连接(因此,成功的结果集),但是当我重新加载时,我得到以下异常:org.hibernate.SessionException:会话关闭!< / p>

以下是我的配置设置,不是与数据库连接字符串相关的:

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

以下是我制作的一个调用示例,它产生了我上面描述的情况。

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

会话变量引用是指包含当前会话的静态字段。所有会话连接详细信息都是教科书参考手册。例如,这是我的Hibernate会话实用程序:

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

1 个答案:

答案 0 :(得分:8)

当您使用sessionFactory.getCurrentSession()获得会话时,会在提交事务时自动刷新并关闭会话(有关详细信息,请参阅Sessions and transactions)。所以,在这里我怀疑1.你得到一次会话一次(这可以解释为什么第一个调用有效以及为什么后续调用失败)这是错误的2.你似乎使用 session-per-operation < / em>反模式甚至更糟。

在Web应用程序中,您应该使用每个请求的会话策略,这意味着“单个会话和单个数据库事务实现特定请求事件的处理”。再次,请参阅Sessions and transactions文档。

如果您想从数据访问代码中删除事务划分,那么您可以使用interceptor在每个请求开始时启动数据库事务,并在请求结束时提交它。请查看Open Session in View以了解此模式的实现(示例DAO展示了这些优势)。