今天程序出现了
引用
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了
分享到:
相关推荐
在使用这个压缩包时,开发者需要按照一定的顺序进行配置:首先设置Hibernate的连接信息和实体映射,然后在Spring中配置数据源、事务管理器和Hibernate SessionFactory,接着配置Struts2的动作类、结果类型和拦截器。...
Spring配置文件中需要配置Hibernate的SessionFactory,以及数据库相关的配置。 ```xml <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> ...
`<context-param>`和`<listener>`元素在`web.xml`中配置Spring的上下文加载。 4. **Tiles**:Tiles是Struts2的一个插件,用于创建和管理复杂的页面布局。它允许将页面拆分为多个组件,每个组件可以独立设计和重用。...
2. **OpenSessionInViewFilter配置**:该过滤器用于解决Hibernate的懒加载问题,在每个请求处理前后开启和关闭Session,确保线程安全和资源释放。 ```xml <!-- 配置OpenSessionInViewFilter --> <filter-name>...
确认类中是否存在对应的setter方法,并确保在Spring配置文件中正确地引用了该setter方法。 #### 运行时报CGLIB出错 检查Spring版本是否与CGLIB兼容,如果存在问题,考虑升级Spring或CGLIB至最新版本。 #### ...
当使用其他框架(如Struts2)时,需要注意`OpenSessionInViewFilter`与这些框架中过滤器的顺序。例如,在上面的例子中,`OpenSessionInViewFilter`被配置在`webwork`过滤器之前,这是为了确保在处理Struts2相关的...
对于Hibernate,需要在Spring配置文件中进行配置,以便利用Spring管理Hibernate的SessionFactory。接着,删除asm2.2.3.jar,并导入commons-pool.jar作为连接池。log4j.properties文件的导入用于日志记录,这对于调试...
除了`EncodingFilter`,在Web应用中还有其他常见的过滤器,如Struts的`TilesFilter`、Hibernate的`OpenSessionInViewFilter`和Spring的`CharacterEncodingFilter`。这些过滤器各有用途,例如`TilesFilter`用于处理...
- 确保所有的配置文件都正确无误,例如web.xml中的过滤器和监听器的配置顺序,以及applicationContext.xml中的bean配置。 - 注意SSH各个组件之间的依赖关系,例如Struts2与Spring的集成、Spring管理Hibernate的...
同时,为了保证页面显示的中文字符正常,需要正确配置OpenSessionInViewFilter和中文编码过滤器。 总的来说,用户菜单管理是一个涉及前端交互、后端逻辑和数据库操作的复杂功能模块。它需要开发者具备扎实的SSH框架...