一、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.*.*(..)
不扫描子包),所有返回值的所有方法,参数不限
*.*(..)
返回值类型.方法名(参数)
三、继续搜集整理