2008-05-07
Hibernate中发生"Session is closed" 的另一种可能
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;
关键字:"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;
- 09:47
- 浏览 (143)
- 论坛浏览 (279)
- 评论 (5)
- 分类: 【软件开发】
- 相关推荐
评论
moshalanye
2008-09-27
回复
open session in view filter 保证方法不在action 的方法执行中遗失掉,保证往上抛到filter层,事务还是可以保证的
魔力猫咪 写道
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
<%@ page contentType="text/html; charset=UTF-8"%>
魔力猫咪 写道
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
<%@ page contentType="text/html; charset=UTF-8"%>
写法很错误。Action只是调用Service的地方,不应该有任何业务代码。这是严禁的。你这么写了,就是破坏了层之间的解耦。业务和表现层框架之间彻底绑死了。除了你这个框架,别人谁也无法调用你的业务。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
其次,也没有你这么写过滤器的。你应该看看Spring和Jdon的Hibernate过滤器。之所以在表现层保持Session,是为了显示延迟加载的对象。所有事务处理都应该由Service处理,表现层不应该过问事务。而且即使是能过问也不能这么写。如果发生异常需要回滚事务,你写法根本无法回滚。你写的只有在提交事务这句的时候出现问题才会回滚。根本无法保证事务完整。
我的相册
ALIM0540
共 2 张
共 2 张
最近加入圈子
链接
最新评论
-
Hibernate中发生"Session ...
open session in view filter 保证方法不在action ...
-- by moshalanye -
Struts中文帮助文档
Thanks for panjun's resource!
-- by lv_pi258 -
Seam能否取代Struts?
拭目以待…… :D
-- by myiris_gm -
Spring MVC与struts比较
:roll: :P :?: :?:  ...
-- by myiris_gm -
提高Java水平的十大技术
可以看出基础的重要,十个里面没有一个是说框架的
-- by spiritfrog







评论排行榜