`
xly_971223
  • 浏览: 1283589 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

spring中OpenSessionInViewFilter的配置顺序问题

阅读更多
今天程序出现了
引用
org.springframework.dao.InvalidDataAccessApiUsageException:
Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

实际上这个问题不是第一次出现了 只是一直没有时间来研究它。今天得闲随即打开了OpenSessionInViewFilter这个文件。 首先先看一下我的web.xml配置
<!-- openSessionInView -->
	<filter>
		<filter-name>openSessionInView</filter-name>
		<filter-class>
			org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>openSessionInView</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!--==================== rewriteFilter ====================-->

	<!--==================== Spring ApplicationContext ====================-->
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:com/redgateonline/showradio/resource/spring/applicationContext*.xml
		</param-value>
	</context-param>

	<!-- ==================== Webwork =================== -->

之前一直怀疑是filter配置的顺序问题 ,有几次修改了配置文件后问题就解决了。
先来看看OpenSessionInViewFilter中的doFilterInternal()方法,这里只给出关键部分,
//从servletContext中取sessionFactory
SessionFactory sessionFactory = lookupSessionFactory(request);
		boolean participate = false;

		if (isSingleSession()) {
			// single session mode
			if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
				// Do not modify the Session: just set the participate flag.
				participate = true;
			}
			else {
				logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
				
Session session = getSession(sessionFactory); //通过sessionFactory获取session,这个session被绑定到当前线程中 在整个request期间使用
				TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
			}
		}
		else {
			// deferred close mode
			if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
				// Do not modify deferred close: just set the participate flag.
				participate = true;
			}
			else {
				SessionFactoryUtils.initDeferredClose(sessionFactory);
			}
		}


看看Session session = getSession(sessionFactory);中的getSession(sessionFactory)是怎么实现的
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
		Session session = SessionFactoryUtils.getSession(sessionFactory, true);
		FlushMode flushMode = getFlushMode();
		if (flushMode != null) {
			session.setFlushMode(flushMode);
		}
		return session;
	}

OpenSessionInViewFilter有一个变量flushMode,可通过getter setter为其赋值,而其默认值为FlushMode.NEVER,这儿的NEVER值已经被deprecate了。
原来是这儿在捣鬼,只要写了子类覆盖setFlushMode(FlushMode.auto);就ok了
分享到:
评论
4 楼 xutao5641745 2011-05-31  
byduke 写道
不知道你是故意的还是也没注意,重写完这个方法以后必须重写里面的close方法

protected void closeSession(SessionFactory sessionFactory,Session session){
    session.flush();
    super.closeSession(sessionFactory,session);
}
不然根本不能运行,楼主不厚道啊,这样容易误导人



说的对。。。。
3 楼 Arden 2009-02-23  
试过了,只覆盖setFlushMode(FlushMode.auto)还不行,最好还是重新写一个,把spring的那个的内容copy过来~然后自己设置下flushMode=FlushMode.AUTO
2 楼 davidcen 2008-06-24  

<bean name="openSessionInViewInterceptor"
		class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
		<property name="flushMode" value="1"/>
		<property name="singleSession" value="true" />
	</bean>

just set flushMode value =1
1 楼 byduke 2008-04-03  
不知道你是故意的还是也没注意,重写完这个方法以后必须重写里面的close方法

protected void closeSession(SessionFactory sessionFactory,Session session){
    session.flush();
    super.closeSession(sessionFactory,session);
}
不然根本不能运行,楼主不厚道啊,这样容易误导人

相关推荐

    jar包(struts2.0.8+spring2.0+hibernate3.2)

    在使用这个压缩包时,开发者需要按照一定的顺序进行配置:首先设置Hibernate的连接信息和实体映射,然后在Spring中配置数据源、事务管理器和Hibernate SessionFactory,接着配置Struts2的动作类、结果类型和拦截器。...

    Struts1.x Spring2.x Hibernate3.x DWR2.x整合工具文档v1.00

    Spring配置文件中需要配置Hibernate的SessionFactory,以及数据库相关的配置。 ```xml &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&gt; ...

    ssh+flex配置

    `&lt;context-param&gt;`和`&lt;listener&gt;`元素在`web.xml`中配置Spring的上下文加载。 4. **Tiles**:Tiles是Struts2的一个插件,用于创建和管理复杂的页面布局。它允许将页面拆分为多个组件,每个组件可以独立设计和重用。...

    ssh配置总结

    2. **OpenSessionInViewFilter配置**:该过滤器用于解决Hibernate的懒加载问题,在每个请求处理前后开启和关闭Session,确保线程安全和资源释放。 ```xml &lt;!-- 配置OpenSessionInViewFilter --&gt; &lt;filter-name&gt;...

    ssha 最新 最完整 配置信息

    确认类中是否存在对应的setter方法,并确保在Spring配置文件中正确地引用了该setter方法。 #### 运行时报CGLIB出错 检查Spring版本是否与CGLIB兼容,如果存在问题,考虑升级Spring或CGLIB至最新版本。 #### ...

    过滤器对于session周期的控制

    当使用其他框架(如Struts2)时,需要注意`OpenSessionInViewFilter`与这些框架中过滤器的顺序。例如,在上面的例子中,`OpenSessionInViewFilter`被配置在`webwork`过滤器之前,这是为了确保在处理Struts2相关的...

    SSH框架搭建.doc

    对于Hibernate,需要在Spring配置文件中进行配置,以便利用Spring管理Hibernate的SessionFactory。接着,删除asm2.2.3.jar,并导入commons-pool.jar作为连接池。log4j.properties文件的导入用于日志记录,这对于调试...

    Java servlet过滤器配置详解

    除了`EncodingFilter`,在Web应用中还有其他常见的过滤器,如Struts的`TilesFilter`、Hibernate的`OpenSessionInViewFilter`和Spring的`CharacterEncodingFilter`。这些过滤器各有用途,例如`TilesFilter`用于处理...

    ssh框架整合增删改查登录注册

    - 确保所有的配置文件都正确无误,例如web.xml中的过滤器和监听器的配置顺序,以及applicationContext.xml中的bean配置。 - 注意SSH各个组件之间的依赖关系,例如Struts2与Spring的集成、Spring管理Hibernate的...

    用户菜单管理

    同时,为了保证页面显示的中文字符正常,需要正确配置OpenSessionInViewFilter和中文编码过滤器。 总的来说,用户菜单管理是一个涉及前端交互、后端逻辑和数据库操作的复杂功能模块。它需要开发者具备扎实的SSH框架...

Global site tag (gtag.js) - Google Analytics