使用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