Spring+Hibernate异常及错误处理——汇总

2 篇文章 0 订阅
1 篇文章 0 订阅
本文详细介绍了在使用Spring和Hibernate进行项目开发时遇到的两个常见问题:一是因版本不一致导致的`execute()`方法调用错误;二是事务配置不当引发的只读模式下不允许写操作的异常。文章提供了问题分析和解决方案,帮助开发者正确配置环境,避免常见的开发陷阱。
摘要由CSDN通过智能技术生成

一、super.getHibernateTemplate()execute(HibernateCallback)

错误信息:

The method execute(HibernateCallback<T>) in the type HibernateTemplate 
is not applicable for the arguments (new HibernateCallback <List<User_Info>>(){}) 

发生错误的代码:

@Override
    public List<User_Info> queryForPage() throws Exception {

        return  this.getHibernateTemplate().execute(  new HibernateCallback<List<User_Info>>(){

            @SuppressWarnings("unchecked")
            @Override
            public List<User_Info> doInHibernate(Session session) throws HibernateException {
                Query query=session.createQuery("from UserInfo");
                return query.list();

            }

        });
    }

原来是包引用错误,引入包的时候一定要小心哦,我是把所有的spring、Hibernate包都添加进工程了,引入的时候一定要注意:

import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

看出来了吧,一个是hibernate3 一个是hibernate5,版本不一致怎么接受这样的参数。我使用的hibernate版本是4.3.9。所有都改成

import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

二、Turn your Session into FlushMode.COMMIT/AUTO or remove ‘readOnly’ marker from transaction

错误信息:

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
    at org.springframework.orm.hibernate4.HibernateTemplate.checkWriteOperationAllowed(HibernateTemplate.java:1128)
    at org.springframework.orm.hibernate4.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:621)
    at 
    。。。。。。。。

问题分析:和明显是事务配置的时候,将方法设置成了readOnly,但明明有写啊。
Hibernate管理事务有5种方式,此工程使用的是tx标签拦截器管理事务,代码如下:
hib-config.xml

<!-- 配置事务管理 -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" >
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<aop:config> 
    <aop:pointcut expression="execution(public * base.user.service.impl.*.*(..))" id="businessService"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="businessService" /> 
</aop:config> 
<tx:advice id="txAdvice" transaction-manager="txManager" > 
    <tx:attributes> 
        <!-- get开头的方法不需要在事务中运行 。 
        有些情况是没有必要使用事务的,比如获取数据。开启事务本身对性能是有一定的影响的  -->
        <tx:method name="query*" read-only="true" propagation="NOT_SUPPORTED"/>  
        <tx:method name="get*" read-only="true" propagation="NOT_SUPPORTED"/> 
        <!-- 其他方法在实务中运行  -->
        <tx:method name="add*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED" />
        <tx:method name="delete*" propagation="REQUIRED" />
        <tx:method name="*" />
    </tx:attributes> 
</tx:advice>

造成此错误的原因可能有两种:
1、事务管理默认将所有的方法配置成readOnly的,这时需要自己指定方法的这个属性值。没指定为就采取默认策略,针对Service中的方法,可以设置tx:advice属性内的值,tx:method指具体的方法设置
2、另一种是,没有将你的Service类加入到事务管理中,所以采用了默认策略,默认策略就是只读的Session。需要设置aop:config属性。
关于该属性设置请参考:
Spring事务管理—aop:pointcut expression解析(转)

**我的错误是第二种原因造成的,对aop:config属性设置理解不够,引用的service包错误,修改为**
<aop:config> 
    <aop:pointcut expression="execution(public * base.user.service..*.*(..))" id="businessService"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="businessService" /> 
</aop:config> 
"execution(public * base.user.service..*.*(..))" 

代表的含义是,扫描base.user.service下的所有公共类类(包括子包,service.*.*(..)不扫描子包),所有返回值的所有方法,参数不限
*.*(..) 返回值类型.方法名(参数)

三、继续搜集整理

PS:如果有分析不对的请留言指正,一起学习,谢谢各位

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值