最近在配置 Structs, 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;
解决办法1:
直接修改OpenSessionInViewFilter过滤器的配置,配置过滤器的时候配置就是在一般的配置里面加上下面蓝色部分就可以了,直接指定flushMode的配置就OK了:
下面是配置文件:(web.xml)
< 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配置:
< bean id = "txManager" class = "org.springframework.orm.hibernate3.HibernateTransactionManager" > < property name = "sessionFactory" ref = "sessionFactory" /> </ bean > < aop:config > < aop:pointcut id = "**" expression = "execution(public * *.*.*..*.*(..))" /> < aop:advisor pointcut-ref = "**" advice-ref = "txAdvice" /> </ aop:config > < tx:advice id = "txAdvice" transaction-manager = "txManager" > < tx:attributes > < tx:method name = "**" read-only = "true" /> < tx:method name = "**" propagation = "REQUIRED" /> </ tx:attributes > </ tx:advice >
下面是总结:
原理:因为配置openSessionInView时,启动后他默认是给没有配置事务边界的方法都默认为只读的,所以在插入数据时就会报上面的错