浏览 2743 次
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间: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; 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-07
我也遇到这样的情况。。。。
呵呵 |
|
返回顶楼 | |
发表时间:2008-05-07
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。 |
|
返回顶楼 | |
发表时间:2008-05-07
魔力猫咪 写道 写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。 <%@ page contentType="text/html; charset=UTF-8"%> |
|
返回顶楼 | |
发表时间:2008-05-07
魔力猫咪 写道 写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。 <%@ page contentType="text/html; charset=UTF-8"%> |
|
返回顶楼 | |
发表时间:2008-09-27
open session in view filter 保证方法不在action 的方法执行中遗失掉,保证往上抛到filter层,事务还是可以保证的
|
|
返回顶楼 | |