OpenSessionInViewFilter更新问题

在项目中配置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在getSession的时候,会把获取回来的session的flushMode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session。
FlushMode.NEVER模式不具备写操作,可以把session配置为FlushMode.AUTO,如在web.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方法实现,如:
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;
	}

}

猜你喜欢

转载自jeyke.iteye.com/blog/1107346