今天在做項目時 spring 和hibernate整合的問題:
開啓OpenSessionInViewFilter來阻止延遲加載的錯誤的時候拋出了這個異常:
org.springframework.dao.InvalidDataAccessApiUsageException錯誤
但是在我們開啓OpenSessionInViewFilter這個過濾器的時候FlushMode就已經被默認設置爲了MANUAL!
如果FlushMode是MANUAL或NEVEL,在操作過程中 hibernate會將事務設置爲readonly,所以在增加、刪除或修改操作過程中會出現如下錯誤:
org.springframework.dao.InvalidDataAccessApiUsageException:
Write operations are not allowed in read-only mode (FlushMode.NEVER) turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition;
解決辦法:
直接修改OpenSessionInViewFilter過濾器的配置,配置過濾器的時候配置就是在一般的配置裏面加上下面部分就可以了,直接指定flushMode的配置就OK了:
<init-param>
<param-name>flushMode</param-name>
<param-value>AUTO</param-value>
</init-param>
下面是配置文件:(web.xml)
<!-- 使用Hibernate延遲加載,會因Session被關閉,導致延遲加載數據異常,等到返回響應後才關閉session -->
<!-- 一定要在struts2過濾器之前 -->
<filter>
<filter-name>hibernateFilter</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>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
總結:網上說了很多種方法,但是試了幾種都沒有效果,實際原因是因爲配置的OpenSessionInView將FlushMode默認設置爲了MANUAL!只要手動將設置爲AUTO就OK了,這種方法最好理解;其次有一種方法是配置事務邊界,個人覺得不容易配置,很容易漏配,所以將FlushMode設置爲了AUTO可以一勞永逸!