您的位置:首页 > 编程语言 > Java开发

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

2015-09-13 01:02 696 查看

一、super.getHibernateTemplate()execute(HibernateCallback)

错误信息:

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


发生错误的代码:

[code]@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包都添加进工程了,引入的时候一定要注意:

[code]import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;


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

[code]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

错误信息:

[code]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

[code]<!-- 配置事务管理 -->
<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解析(转)

[code]**我的错误是第二种原因造成的,对aop:config属性设置理解不够,引用的service包错误,修改为**


[code]<aop:config> 
    <aop:pointcut expression="execution(public * base.user.service..*.*(..))" id="businessService"/> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="businessService" /> 
</aop:config>


[code]"execution(public * base.user.service..*.*(..))"


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

*.*(..)
返回值类型.方法名(参数)

三、继续搜集整理

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: