Spring+Hibernate異常及錯誤處理——彙總

一、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:如果有分析不對的請留言指正,一起學習,謝謝各位

發佈了38 篇原創文章 · 獲贊 10 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章