您的位置:首页 > 运维架构

OpenSessionInViewFilter更新问题

2015-03-26 14:59 351 查看
OpenSessionInViewFilter更新问题

SpringHibernateDAOXMLORM
在项目中配置OpenSessionInViewFilter后,首先会出现的问题:

Java代码

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在getSession的时候,会把获取回来的session的flushMode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session。

FlushMode.NEVER模式不具备写操作,可以把session配置为FlushMode.AUTO,如在web.xml中配置:

Xml代码

<filter>
<filter-name>OpenSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
</filter>

其次,会遇到的另外一个问题是页面更新操作,因为这个流程是:首先查询取得数据库中的记录,修改客户端改变的属性,更新这个实体类。这是通过以上配置OpenSessionInViewFilter,在session更新实体类之前,session已经存在一个实体类,与客户端传过来的需要修改的实体类会发生冲突,以致更新失败。这个可以通过配置singleSession=false解决。也可以通过重写OpenSessionInViewFilter类的getSession及closeSession方法实现,如:

Java代码


public class MyOpenSessionInViewFilter extends OpenSessionInViewFilter{

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

@Override
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.beginTransaction();
FlushMode flushMode = getFlushMode();
if (flushMode != null) {
this.setFlushMode(FlushMode.AUTO);
}
return session;
}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: