这是控制台的错误信息
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:72)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1456)
at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:344)
at $Proxy0.beginTransaction(Unknown Source)
at cn.edu.xmut.filter.HibernateSessionFilter.doFilter(HibernateSessionFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:873)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:619)at cn.edu.xmut.filter.HibernateSessionFilter.doFilter(HibernateSessionFilter.java:37)
这一行的代码是:
public class HibernateSessionFilter implements Filter { private Transaction tx;
private SessionFactory sessionfactory;
public void destroy() { sessionfactory.close();
} public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
try
{
Session session = sessionfactory.getCurrentSession();
//System.out.println("session state="+session.isOpen());当出现错误的时候打印,结果为false
if(!session.isOpen()){
session=SessionFactoryUtil.getSessionFactory().getCurrentSession();
//System.out.println("session state="+session.isOpen());//重新生成session,依然是false
}
tx=session.beginTransaction();//控制台提示错误的那一行
chain.doFilter(request, response);
if(tx.isActive())
{
tx.commit(); }
}catch(Exception e)
{
e.printStackTrace();
if(tx.isActive())
{
tx.rollback();
}
}
} public void init(FilterConfig arg0) throws ServletException {
sessionfactory=SessionFactoryUtil.getSessionFactory();
}}有时候出现这个问题,有时候不出现,重启tomcat又不会了.

解决方案 »

  1.   

    楼上的人,你发的bug影响我求助了,你很缺德
      

  2.   

    session = SessionFactoryUtil.getSessionFactory().getCurrentSession();
    该个
    session = SessionFactoryUtil.getSessionFactory().openSession();看看
      

  3.   

    谢谢你的回答.我还没有试你的方法,能不能麻烦你讲一下错误原因,因为如果要改的话,我的项目中全部是使用getCurrentSession()获得的session,要修改很多地方,有没有其他比较好的方法
      

  4.   

    我90%确定,你是能得到session的,但是你得到的session是一个关闭的session。,也就是说你执行getCurrentSession()的确得到了一个session,但是是一个关闭的session。如果答案有用就把你的分都借我吧。。
      

  5.   

    的确,是可以得到,但是得到的是关闭的session,是什么原因呢,麻烦说一下。
      

  6.   

    session open过了吗?
    if(!session.isOpen()){
          //session 没有打开过, 打开
          session = SessionFactoryUtil.getSessionFactory().openSession();
    } else {
          //session 打开过,获取当前session
          session=SessionFactoryUtil.getSessionFactory().getCurrentSession();
    }
      

  7.   

    谢谢楼上的回答,但是opensession好像也是获得一个session,而不是打开session,而且getcurrentsession也是用来获得session.
      

  8.   

    既然你在我的留言板上留了言,那我只能来回复一下说抱歉了——我不会 Hibernate 呢。private Transaction tx; 你把这个改成局部变量试试看。
      

  9.   

    使用SessionFactory.getCurrentSession()
    需要在hibernate.cfg.xml中配置:
    <property name="hibernate.current_session_context_class">thread</property>
    用这个试试看。
      

  10.   

    看了一下 Hibernate 的源代码,如果使用 getCurrentSession 的话,并且 Hibernate 属性hibernate.current_session_context_class 值为 thread 的话会绑定到本地线程对象中去。使用 getCurrentSession 打开的会在提交或者回滚时自动关闭,会执行清理工作。你看一下,把 hibernate.current_session_context_class 值设为 thread。可以参考 Hibernate 的文档《Open Session in View》,那里有个 Filter 的实现。
    http://community.jboss.org/wiki/OpenSessioninView
      

  11.   

    sessionFactoryUtil里面估计写的有问题
      

  12.   

    这是SessionFactoryUtil的源码.不知道是否存在问题,麻烦你帮我看看
    public class SessionFactoryUtil {
    private static SessionFactory sf;
    static
    {
    sf=new Configuration().configure().buildSessionFactory();
    }
    public static SessionFactory getSessionFactory()
    {
    return sf;
    }
    public static void close()
    {
    sf.getCurrentSession().beginTransaction().commit();
    }
    }
      

  13.   

    我在认真看那个文档,设置hibernate.current_session_context_class 值为 thread ,我有设置,而且我的问题是有时候出现,有时候不出现
      

  14.   

    那只能在出现时把 Hibernate 的 DEBUG 日志贴出来看一下。
      

  15.   

    你这个问题是当tomcat运行一段时间后就会出现
    当重启tomcat后就会消失 
    代码没有什么问题 
    就是异常处理的不全面 
    要先看什么原因出现这个异常 1 是否有多余的连接 
    2 是否用户没有正常退出系统(直接关闭浏览器 不是点击退出或注销按钮)
    希望对你有用 好运
      

  16.   


    我不知道你这个是否改了?刚才看了一下你的代码,在 commit 和 rollback 中有 isActive,如果这个返回的是 false 的话,那么并不会执行提交回滚什么的,那 ThreadLocalSessionContext 也就不能做清理工作了。你看一下,能否在 finally 中将非 null 的 session 给 close 掉。根据 ThreadLocalSessionContext 的源代码在执行 session 的 close 时会进行清理工作。
      

  17.   

    我个人是很反对使用 open session in view filter 模式的,这种控制事务的模式需要借助一个过滤器,过滤器有个特点,只要 url-pattern 是 /* 的话,那就会过滤所有的访问 URL。采用这种模式的话,哪怕访问个静态资源都会去创建一个 session,实际上这个 session 没有任何用处,浪费了一个数据库宝贵的连接。建议将事务边界定义在业务方法上,而不是其定义在一个 request 上。
      

  18.   

    hibernate配置文件中 把lazy从true该成false,让查询的时候,查询出所有关联的数据如果没有lazy  添加上lazy="false"这属于偷懒的行为 
      

  19.   

    没有及时关闭连接 再有用户登录 是你的可用连接数减少
    举个例子 
    假如 你有一个房间(系统) 你有200个钥匙 当有人要进房间的时候你的管家会给他一把钥匙 当他离开时归还钥匙与管家(正常退出或注销) 
    非正常时(没有归还钥匙给管家) 这样一直下去 200个钥匙总有用完的时候
    当有一个人未归还钥匙时  你只能提供(200-1)个钥匙提供给要进房间的人
    think over
      

  20.   

    SessionFactoryUtil  
     public static void close()
        {
            sf.getCurrentSession().beginTransaction().commit();
        }
    把这个方法去掉。不要调用这个方法。
    前面已提交过。
    试试看吧。
      

  21.   

    以前也出现过类似的情况就是hibernate配置文件中  把lazy从true该成false,让查询的时候,查询出所有关联的数据如果没有lazy 添加上lazy="false"
      

  22.   

    还不明白吗? 意思你放进去的session的确是开着的。但是我把session关闭了,你取出来的session就是关闭了,你取出来的session是开是关 和你放进去的session无关。或者这么和你说,你代码里面在不应该关闭session的地方关闭了session。 我不知道你为什么要关闭它。有时候是不需要关闭了。光看这个类应该看不出来什么错误要结合其他去看的。
      

  23.   

    你的mysql密码和你Hiber配置文件里的密码不一致!
      

  24.   

    那需要怎么解决呢? 当第一次出现session is cloased的时候,就算请求一个静态页面,也会出现这个异常,然后导致页面空白,或者排版变乱
      

  25.   

    加点日志吧,否则啥都看不出来:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        Transaction tx = null;
        try {
            Session session = sessionfactory.getCurrentSession();
            log.debug("filter get session: " + session + ", isOpen? " + session.isOpen());
            if(!session.isOpen()){
                log.debug("filter current session isClosed, error");  // TO-DO
                session=SessionFactoryUtil.getSessionFactory().getCurrentSession(); // 这句话没用,意义跟上面那句一样!
            }
            tx = session.beginTransaction();
            logTx(tx, "start transaction, and execute filter chain");
            chain.doFilter(request, response);
            logTx(tx, "filter chain finished, then process transaction");
            if(tx.isActive()) {
                tx.commit();
                logTx(tx, "transaction commit finished");
            }
        } catch(Exception e) {
            log.error("exception throwed, to rollback transaction...");
            if(tx.isActive()) {
                tx.rollback();
                logTx(tx, "transaction rollback finished");
            }
        }
    }private void logTx(Transaction tx, String info) {
        if(log.isDebugEnabled()) {
            if(tx == null) {
                log.debug(info + ", but transaction is null!");
                return;
            }
            log.debug(info + ", transaction " + tx + ", isActive? " + tx.isActive());
        }
    }
      

  26.   

    暂时还没发现问题,我用你给我的那个文档重写了一边HibernateSessionFilter ,真是麻烦你了. 不知道解决了没有.