一、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.*.*(..)
不掃描子包),所有返回值的所有方法,參數不限
*.*(..)
返回值類型.方法名(參數)
三、繼續蒐集整理