hibernate異常:
解決Hibernate的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.
方法一:在出現異常的方法中加入:
getHibernateTemplate().setFlushMode(HibernateTemplate.FLUSH_EAGER);
方法二:重寫OpenSessionInViewFilter:
package cn.com.farben.framework.util; import org.hibernate.FlushMode;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.dao.DataAccessResourceFailureException;import org.springframework.orm.hibernate3.SessionFactoryUtils; public class OpenSessionInViewFilter extends org.springframework.orm.hibernate3.support.OpenSessionInViewFilter { protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { Session session = SessionFactoryUtils.getSession(sessionFactory, true); session.setFlushMode(FlushMode.COMMIT); return session; } protected void closeSession(Session session, SessionFactory factory) { session.flush(); super.closeSession(session, factory); }}
web.xml
<filter> <filter-name>hibernateFilter</filter-name> <filter-class>cn.com.farben.framework.util.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param></filter><filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
問題:唯讀模式下(FlushMode.NEVER/MANUAL)寫操作不被允許:把你的Session改成FlushMode.COMMIT/AUTO或者清除事務定義中的readOnly標記。
錯誤原因:
OpenSessionInViewFilter在getSession的時候,會把擷取回來的session的flush mode 設為FlushMode.NEVER。然後把該sessionFactory綁定到TransactionSynchronizationManager,使request的整個過程都使用同一個session,在請求過後再接除該sessionFactory的綁定,最後closeSessionIfNecessary根據該session是否已和transaction綁定來決定是否關閉session。在這個過程中,若HibernateTemplate
發現自當前session有不是readOnly的transaction,就會擷取到FlushMode.AUTO Session,使方法擁有寫入權限。也即是,如果有不是readOnly的transaction就可以由Flush.NEVER轉為Flush.AUTO,擁有insert,update,delete操作許可權,如果沒有transaction,並且沒有另外人為地設flush
model的話,則doFilter的整個過程都是Flush.NEVER。所以受transaction(聲明式的事務)保護的方法有寫入權限,沒受保護的則沒有。