錯(cuò)誤代碼:
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
錯(cuò)誤原因:
OpenSessionInViewFilter在getSession的時(shí)候,會(huì)把獲取回來(lái)的session的flush mode 設(shè)為FlushMode.NEVER。然后把該sessionFactory綁定到TransactionSynchronizationManager,使request的整個(gè)過(guò)程都使用同一個(gè)session,在請(qǐng)求過(guò)后再解除該sessionFactory的綁定,最后closeSessionIfNecessary根據(jù)該session是否已和transaction綁定來(lái)決定是否關(guān)閉session。在這個(gè)過(guò)程中,若HibernateTemplate 發(fā)現(xiàn)自當(dāng)前session有不是readOnly的transaction,就會(huì)獲取到FlushMode.AUTO Session,使方法擁有寫(xiě)權(quán)限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER轉(zhuǎn)為Flush.AUTO,擁有insert,update,delete操作權(quán)限,如果沒(méi)有transaction,并且沒(méi)有另外人為地設(shè)flush model的話,則doFilter的整個(gè)過(guò)程都是Flush.NEVER。所以受transaction保護(hù)的方法有寫(xiě)權(quán)限,沒(méi)受保護(hù)的則沒(méi)有。
參考文章:
http://calvin.blog.javascud.org/post/46.htm
解決辦法:
采用spring的事務(wù)聲明,使方法受transaction控制
<bean id="baseTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userService" parent="baseTransaction">
<property name="target">
<bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
</property>
</bean>
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
錯(cuò)誤原因:
OpenSessionInViewFilter在getSession的時(shí)候,會(huì)把獲取回來(lái)的session的flush mode 設(shè)為FlushMode.NEVER。然后把該sessionFactory綁定到TransactionSynchronizationManager,使request的整個(gè)過(guò)程都使用同一個(gè)session,在請(qǐng)求過(guò)后再解除該sessionFactory的綁定,最后closeSessionIfNecessary根據(jù)該session是否已和transaction綁定來(lái)決定是否關(guān)閉session。在這個(gè)過(guò)程中,若HibernateTemplate 發(fā)現(xiàn)自當(dāng)前session有不是readOnly的transaction,就會(huì)獲取到FlushMode.AUTO Session,使方法擁有寫(xiě)權(quán)限。
也即是,如果有不是readOnly的transaction就可以由Flush.NEVER轉(zhuǎn)為Flush.AUTO,擁有insert,update,delete操作權(quán)限,如果沒(méi)有transaction,并且沒(méi)有另外人為地設(shè)flush model的話,則doFilter的整個(gè)過(guò)程都是Flush.NEVER。所以受transaction保護(hù)的方法有寫(xiě)權(quán)限,沒(méi)受保護(hù)的則沒(méi)有。
參考文章:
http://calvin.blog.javascud.org/post/46.htm
解決辦法:
采用spring的事務(wù)聲明,使方法受transaction控制
<bean id="baseTransaction"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userService" parent="baseTransaction">
<property name="target">
<bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
</property>
</bean>