首页 > Hibernate, Java, Spring > 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.

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.

2009年12月31日 IT北瓜 发表评论 阅读评论

昨天遇到这个异常“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.”大概意思是说试图在只读模式下向数据库插入内容。由于出现这个异常的时候刚好要下班了,所以今天才把这个异常解决了,在这里记录一下。

由于博客上没有装代码高亮插件,都是用Windows Live Writer写文章,现在的这个电脑上没安装Windows Live Writer,所以一下内容引用代码的部分就没办法高亮显示了,不过涉及的代码不多,讲究着吧~~~

问题分析:上面的异常总的来说是由于lazy机制引起的,我们知道懒加载问题一般都是通过配置OpenSessionInViewFilter来解决。原先web.xml中配置OpenSessionInViewFilter部分的代码如下:

<filter>
<description>处理Hibernate的懒加载问题</description>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

解决方法:其实异常信息中已经很清楚的告诉我们解决方法了,异常中说到需要把session改为FlushMode.COMMIT(或者FlushMode.AUTO),抑或去掉Spring事务配置中的readOnly。这里Leeo选择将session改为FlushMode.COMMIT的方式。具体做法是自己写一个类继承org.springframework.orm.hibernate3.support.OpenSessionInViewFilter,代码如下:

import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

public class OpenSessionInViewFilter extends
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter {
/**
* we do a different flushmode than in the codebase
* here
*/
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.COMMIT);
return session;
}
/**
* we do an explicit flush here just in case
* we do not have an automated flush
*/
protected void closeSession(Session session, SessionFactory factory) {
session.flush();
super.closeSession(session, factory);
}

}

然后只要把原先web.xml中的

<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>

org.springframework.orm.hibernate3.support.OpenSessionInViewFilter改为刚刚写的类的包路径就可以了,即:

<filter-class>
com.frscs.util.OpenSessionInViewFilter
</filter-class>

暂无关联文章!

分类: Hibernate, Java, Spring 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.

注意: 评论者允许使用'@user空格'的方式将自己的评论通知另外评论者。例如, ABC是本文的评论者之一,则使用'@ABC '(不包括单引号)将会自动将您的评论发送给ABC。使用'@all ',将会将评论发送给之前所有其它评论者。请务必注意user必须和评论者名相匹配(大小写一致)。