org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read

org.springframework.dao.InvalidDataAccessApiUsageException: 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.  
就是这个问题,在对数据库进行 save 和 update 操作时,一直报错不成功。

一开始我一直以为是 applicationContext.xml的配置问题,因为项目由hibernate3升级到了4,Spring3升级到了Spring4。

所以一直就认为是配置文件的问题,后来各种百度,各种查资料,发现配置文件没什么问题,那就奇了怪了,找不到原因了,还是纠结在 配置文件上面了,我看到有人给 事务 的配置是这样写的:

1.<tx:advice id="advice" transaction-manager="transactionManager">
         <tx:attributes>
             <tx:method name="add*" propagation="REQUIRED"/>
             <tx:method name="save*" propagation="REQUIRED"/>
             <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>
         </tx:attributes>
 </tx:advice>
     
     配置切面表达式, 并且让 tx与切面表达式合二为一
     <aop:config>
         表达式, 定义哪个包的哪些类需要切入事务,但是此处并且没有制定类中哪些方法,需要切入什么样 事务
         <aop:pointcut expression="execution(* news.service.*.*(..))" id="pointcut" />
         <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/>
     </aop:config>

其实对于那个 切面表达式 配置,我并不是很懂,id="pointcut"不知道是给哪里用的,重点放在了tx:advice 的配置上,其实之前我的配置是这样的:

2.<tx:annotation-driven transaction-manager="transactionManager" />

然后我把我的改成了 上面人家提供的,因为 <tx:method> 里面写出的save,update那些方法,read-only 默认为 false,我本以为会成功了,谁曾想,连applicationContext.xml 都加载失败了,于是又改回了原来我的配置方式。

后来才发现,其实这两个没什么太大的区别,都是 声明式事务管理,只不过 1 是 xml方式的配置,而 2 是注解是配置。

所以用2没问题。那我又把重点放在了BaseDao的方法上,会不会是Hibernate的save和update方法写错了,先说一下BaseDao,是我们自己写的底层dao方法,继承了HibernateDaoSupport:

public class BaseDao<T> extends HibernateDaoSupport {
	 @Resource(name="sessionFactory")  
	    public void setSuperSessionFactory(SessionFactory sessionFactory) {  
	        super.setSessionFactory(sessionFactory);  
	    }
	 /** 
     * 创建一个Class的对象来获取泛型的class 
     */ 
	public Class<T> entityClass;

	@SuppressWarnings("unchecked")  
    public Class<T> getClz(){  
        if (entityClass==null) {  
        	entityClass=(Class<T>)(((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);  
        }  
        return entityClass;  
    } }                                                                           

我为什么会纠结与Dao方法写错了呢,是因为!!!!!!我看有人说 getHibernateTemplate() 在hibernate3中适用,在hibernate4中不能用了,所以我就以为是不兼容的问题,但自己对hibernate源码又不熟,并不知道要怎么改。


真的是纠结死了,,,,,

然后又回过头看 报的错,还是read-only的问题,然后我在Dao的update和save方法上面加上了

 @Transactional(readOnly=false)

我的天,竟然这就这个问题,加上它就可以save和update了,,,真的是很惊讶。不是说hibernate4不能用 getHibernateTemplate()这个方法了吗????


虽然问题解决了,可还是存在一些疑问,尤其是配置文件,对于配置文件,真的是很麻烦的问题,等以后知识储备够了再回过头来研究吧,到时候应该就不是什么问题啦哈哈。




猜你喜欢

转载自blog.csdn.net/alinekang/article/details/80509008