论坛首页 入门技术论坛

Hibernate中发生"Session is closed" 的另一种可能

浏览 2706 次
该帖已经被评为新手帖
作者 正文
   发表时间:2008-05-07  
Hibernate中发生"Session is closed" 的另一种可能:没有commit的Transaction。
关键字:"Session is closed" Hibernate
一般的在struts加Hibernate的项目中!大家想必都使用的HibernateUtil和CloseSessionFilter!
也许很多人,只是对上面的两个类只是用一用,大概都没有仔细地研究过吧,我也是一样!

在过渡器中有这样的代码!
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
try{
chain.doFilter((HttpServletRequest)request, (HttpServletResponse)response);
}
finally{
try{
HibernateUtil.commitTransaction();
//System.out.println("commit ok");
}catch (Exception e){
HibernateUtil.rollbackTransaction();
}finally{
HibernateUtil.closeSession();
}
}
}

在项目开始前一段时期,总觉的每开一个session都要commit一次事务,有些浪费(看不惯"没有作用"的代码)!就这样把它给删了!

在项目开发后运行中,在某个Action中下列代码处
HibernateUtil.beginTransaction()
//省略的代码
//这几句是业务逻辑处理
if(!this.checkYRGS(mcdjForm))
{
Msg.addError(request,new ActionMessage("mcdj.yrgs"));
return mapping.getInputForward(); //这样就有了一个没有commit的Transaction! 这就是问题的根源!
}
//省略的代码
HibernateUtil.commitTransaction();
return mapping.getInputForward("下一个流程页面");

如果有一次在上面的业务逻辑处理处发生了跳转(产生没有commit的Transaction),则下一次运行到
任何处的HibernateUtil.commitTransaction();就会发生异常:Session is closed。!

经过很久的上网搜索和不断的测试(打印相关session和transaction的对象的hashcode),
发现每个不同session的使用session.beginTransaction()获得的transaction对象都是一样的。

总之session.beginTransaction()并不能保证获得的是一个全新transaction对象,也不能保证这个transaction对象与
当前的session进行了关联!

觖决办法:
在filter中commitTransaction(),或在程序中commitTransaction()就行了。一定要保证transaction对象要commit;
   发表时间:2008-05-07  
我也遇到这样的情况。。。。
呵呵
0 请登录后投票
   发表时间:2008-05-07  
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
0 请登录后投票
   发表时间:2008-05-07  
魔力猫咪 写道
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。

<%@ page contentType="text/html; charset=UTF-8"%>
0 请登录后投票
   发表时间:2008-05-07  
魔力猫咪 写道
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。

<%@ page contentType="text/html; charset=UTF-8"%>
0 请登录后投票
   发表时间:2008-09-27  
open session in view filter 保证方法不在action 的方法执行中遗失掉,保证往上抛到filter层,事务还是可以保证的
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics