最近在配置 Structs, spring 和hibernate整合的问题:java
开启OpenSessionInViewFilter来阻止延迟加载的错误的时候抛出了这个异常:web
org.springframework.dao.InvalidDataAccessApiUsageException错误spring
可是在咱们开启OpenSessionInViewFilter这个过滤器的时候FlushMode就已经被默认设置为了MANUAL!数据库
若是FlushMode是MANUAL或NEVEL,在操做过程当中 hibernate会将事务设置为readonly,因此在增长、删除或修改操做过程当中会出现以下错误:express
org.springframework.dao.InvalidDataAccessApiUsageException:session
Write operations are not allowed in read-only mode (FlushMode.NEVER) turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition;app
解决办法1:url
直接修改OpenSessionInViewFilter过滤器的配置,配置过滤器的时候配置就是在通常的配置里面加上下面蓝色部分就能够了,直接指定flushMode的配置就OK了:spa
下面是配置文件:(web.xml).net
<filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <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>
解决方法2:
就是配置事务的边界,在你方法的执行时配置事务边界!
下面是sessionFactor.xml配置:
<!-- 事务的配置 --> <!-- sessionFactory 为本身配置 sessionFactory 的 bean--> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <aop:config> <!-- execution(public * *.*.*..*.*(..)) 为本身项目中操做数据库中的方法 --> <aop:pointcut id="**" expression="execution(public * *.*.*..*.*(..))" /> <aop:advisor pointcut-ref="**" advice-ref="txAdvice" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <!-- name 为 方法名 --> <tx:method name="**" read-only="true" /> <tx:method name="**" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
下面是总结:
原理:由于配置openSessionInView时,启动后他默认是给没有配置事务边界的方法都默认为只读的,因此在插入数据时就会报上面的错
若是出现该错误,检查事务边界配置是否正确
原文地址:http://blog.csdn.net/enterys/article/details/7927840