spring的OpenSessionInViewFilter问题(spring2.5+hibernate-3.2.6+struts1.X)

kingbillow 2008-04-28 10:33:35
我重写了OpenSessionInViewFilter类,在struts的action中先向数据库添加一条数据,然后再查询所有的数据,但是无法得到最新插入的一条数据

打印了hibernate的sql显示是先查询,然后才执行了数据库的插入操作,怎么回事呢?
web.xml
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>com.test.util.ExtOpenSessionInViewFilter</filter-class>
<!--filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class-->
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>


public class ExtOpenSessionInViewFilter extends OpenSessionInViewFilter{
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
this.setFlushMode(FlushMode.AUTO);
/*FlushMode flushMode = getFlushMode();
if (flushMode != null) {
session.setFlushMode(flushMode);
} */
return session;
}

protected void closeSession(Session session, SessionFactory sessionFactory){
session.flush();
super.closeSession(session, sessionFactory);
}

}



Hibernate: select book0_.id as id0_, book0_.name as name0_ from test_book book0_
Hibernate: insert into test_book (name, id) values (?, ?)
...全文
426 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
sunyujia 2008-05-02
  • 打赏
  • 举报
回复
楼主配置上声明事务就行了,spring这么有名的框架,不会随便搞个没有用的类让我们去二次修改的,既然很多人用,都没问题就说明你的用法不规范,我都用了快两年了也没什么问题,2个项目都这么干的.别把他搞复杂了,spring的意图就是simple
kingbillow 2008-04-29
  • 打赏
  • 举报
回复
kyo100900:
不能每次有事务时我都传递一个参数吧?

对于事务是不是会检查当前有没有需要处理的,如果没有事务也不会起什么作用?
kyo100900 2008-04-28
  • 打赏
  • 举报
回复
public class ExtOpenSessionInViewFilter extends OpenSessionInViewFilter{
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
this.setFlushMode(FlushMode.AUTO);
/*FlushMode flushMode = getFlushMode();
if (flushMode != null) {
session.setFlushMode(flushMode);
} */
return session;
}

protected void closeSession(Session session, SessionFactory sessionFactory){
session.flush();
super.closeSession(session, sessionFactory);
}

}



改成



public class ExtOpenSessionInViewFilter extends OpenSessionInViewFilter{
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.beginTransaction();
this.setFlushMode(FlushMode.AUTO);
/*FlushMode flushMode = getFlushMode();
if (flushMode != null) {
session.setFlushMode(flushMode);
} */
return session;
}

protected void closeSession(Session session, SessionFactory sessionFactory){
session.flush();
session.getTransaction().commit();
super.closeSession(session, sessionFactory);
}

}

试试吧, 我感觉光flush不commit,要写进数据库的资源一直在JVM所托管的内存中,还得commit一下
gongyali2005 2008-04-28
  • 打赏
  • 举报
回复
不明白为什么要重写这个类.

传说这个类只是为了把用户的一些操作,作为一个事务来处理.
sunyujia 2008-04-28
  • 打赏
  • 举报
回复
有怎么复杂吗只要使用spring挂上声明式事务就可以写了操作了,就这样,不建议你大改动.
kyo100900 2008-04-28
  • 打赏
  • 举报
回复
再回一次吧:
OpenSessionInViewFilter类的

private FlushMode flushMode = FlushMode.NEVER; 默认设置是NEVER


再回过来看Hibernate源代码:

/**
* The {@link Session} is never flushed unless {@link Session#flush}
* is explicitly called by the application. This mode is very
* efficient for read only transactions.
*
* @deprecated use {@link #MANUAL} instead.
*/
public static final FlushMode NEVER = new FlushMode( 0, "NEVER" );


临远 2008-04-28
  • 打赏
  • 举报
回复
没说非要readOnly啊。
osiv允许里边带有嵌套事务。我觉得用老的osiv没啥问题,配合spring的support,没必要自己写什么commit的。
当然,有时候需要flush还是要flush一下的。
kyo100900 2008-04-28
  • 打赏
  • 举报
回复
Spring原本建议使用OpenSessionInViewFilter时,事务是readOnly的,但你却一定要insert数据的话
是必须事务提交的。
既然已经改Spring类了,再改改也无所谓了:
在方法,假设需要使用事务时,传递了一个参数叫isTransaction

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException{
...................
String isTransaction = request.getParameter("isTransaction");
if(StringUtils.isNotBlank(isTransaction)){
session.beginTransaction();
}
......................
........................

}

同理,关闭方法也根据这个参数来设置:

protected void closeSession(Session session, SessionFactory sessionFactory, String isTransaction){
session.flush();
if(StringUtils.isNotBlank(isTransaction)){
session.getTransaction().commit();
}
super.closeSession(session, sessionFactory);
}


差不多了吧,不需要我再多说了吧。
kingbillow 2008-04-28
  • 打赏
  • 举报
回复
楼上的方法可以,但是这样的话不是每次都会提交一下,而不管是否有数据需要提交,会不会影响性能?
spring2.5学习PPT 传智博客 01_全面阐释Spring及其各项功能 02_搭建与测试Spring的开发环境 03_编码剖析Spring管理Bean的原理 04_Spring的三种实例化Bean的方式 05_配置Spring管理的bean的作用域 06_Spring管理的Bean的生命周期 07_编码剖析Spring依赖注入的原理 08_编码剖析Spring装配基本属性的原理 09_Spring如何装配各种集合类型的属性 10_使用构造器装配属性 11_用@Resource注解完成属性装配 12_编码剖析@Resource注解的实现原理 13.@Autowire注解与自动装配 14.让Spring自动扫描和管理Bean 15.使用JDK中的Proxy技术实现AOP功能 16.使用CGLIB实现AOP功能与AOP概念解释 17.使用Spring的注解方式实现AOP入门 18.使用Spring的注解方式实现AOP的细节 19.使用Spring配置文件实现AOP 20.aspectj的切入点语法定义细节 21.搭建和配置Spring与jdbc整合的环境 22.Spring集成的jdbc编码和事务管理 23.使用Spring注解方式管理事务与传播行为详解 24.使用Spring配置文件实现事务管理 25.搭建和配置SpringHibernate整合的环境 26.Spring集成的Hibernate编码与测试 27.Struts与Spring集成方案1(Struts集成Spring) 28.Struts与Spring集成方案2(Spring集成Struts) 29.为Spring集成的Hibernate配置二级缓存 30.Spring提供的CharacterEncoding和OpenSessionInView功能 31.使用Spring集成JPA 32.Struts+Spring+JPA集成 33.使用Spring集成Struts2 34.所有源码

67,538

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧