Write operations are not allowed in read-only mode

使用Spring提供的Open Session In View而引起Write operations are not allowed in read-only mode (FlushMode.NEVER) 错误解决:

       在没有使用Spring提供的Open Session In View情况下,因需要在service(or Dao)层里把session关闭,所以lazy loading 为true的话,要在应用层内把关系集合都初始化,如 company.getEmployees(),否则Hibernate抛session already closed Exception;    Open Session In View提供了一种简便的方法,较好地解决了lazy loading问题.

它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配置,另一个在application.xml配置而已。

Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间都可以使用,如在View层里PO也可以lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会通过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。

 

解决方案:

《一》我实践过,这个filter写在最前面 保险

在 web.xml配置里添加 
<filter> 
   <filter-name>OpenSessionInViewFilter</filter-name> 
   <filter-class> 
    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter 
   </filter-class> 
   <init-param> 
    <param-name>sessionFactoryBeanName</param-name> 
    <param-value>sessionFactory</param-value> 
   </init-param> 
   <init-param> 
            <param-name>singleSession</param-name> 
            <param-value>true</param-value>            
        </init-param> 
        <init-param> 
        <param-name> flushMode </param-name> 
   <param-value>AUTO </param-value>         
        </init-param> 
</filter> 
     。。。。 


<filter-mapping> 
   <filter-name>OpenSessionInViewFilter</filter-name> 
   <url-pattern>/*</url-pattern> 
</filter-mapping> 

 

《二》

般这个错误是事务引起的,如果确定事务没有问题,还是有这个错,可以重写OpenSessionInViewFilter的2个方法

在myfaces的wiki里提供了OpenSessionInViewFilter的一个子类如下:
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);
        }
}

你可能感兴趣的:(Write operations are not allowed in read-only mode)