使用Spring提供的Open Session In View而引发Write operations are not allowed in read-only mode (FlushMode.NEVER) 错误解决: web
在没有使用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问题. spring
它有两种配置方式OpenSessionInViewInterceptor和OpenSessionInViewFilter(具体参看SpringSide),功能相同,只是一个在web.xml配置,另外一个在application.xml配置而已。 session
Open Session In View在request把session绑定到当前thread期间一直保持hibernate session在open状态,使session在request的整个期间均可以使用,如在View层里PO也能够lazy loading数据,如 ${ company.employees }。当View 层逻辑完成后,才会经过Filter的doFilter方法或Interceptor的postHandle方法自动关闭session。 app
解决方案: ide
《一》我实践过,这个filter写在最前面 保险 post
在 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> url
《二》 spa
般这个错误是事务引发的,若是肯定事务没有问题,仍是有这个错,能够重写OpenSessionInViewFilter的2个方法 hibernate
在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);
}
} code