今天在用传统框架ssh时出现了如题的错误,版本是hibernate4.x和struts2.x和spring4.x。之前用hibernate3.x和spring3.x还好好的,代码如下
,它会决定是否代理session,导致session强制转换SessionImplementor的时候出错。在execute();这个里面已经将他的值设为了false也就是说这个这个没法解决了吗,当然不是,HibernateTemplate这个模板中还有个方法executeWithNativeSession()我们来看一看它的方法体
@Override
public Integer getCount(final DetachedCriteria dc) throws Exception{
return getHibernateTemplate().execute(new HibernateCallback(){
@Override
public Object doInHibernate(Session session) throws HibernateException {
return ((Long) dc.getExecutableCriteria(session).uniqueResult()).intValue();
}
});
}
但是运行时报出如下错误
java.lang.ClassCastException: com.sun.proxy.$Proxy25 cannot be cast to org.hibernate.engine.spi.SessionImplementor
at org.hibernate.criterion.DetachedCriteria.getExecutableCriteria(DetachedCriteria.java:75)
at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:341)
at org.springframework.orm.hibernate4.HibernateTemplate.execute(HibernateTemplate.java:296)
网上找了下看到大多数是说要给spring的
<aop:config></aop:config> 改成
<aop:config proxy-target-class="true"></aop:config>
结果还是报错这个错误,没办法,只好自己找了,看了一下org.springframework.orm.hibernate4.HibernateTemplate源码的两个片段,如下
@Override
public <T> T execute(HibernateCallback<T> action) throws DataAccessException {
return doExecute(action, false);
}
protected <T> T doExecute(HibernateCallback<T> action, boolean enforceNativeSession) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
//挑出了下面这段其余省略
**try {
enableFilters(session);
Session sessionToExpose =
(enforceNativeSession || isExposeNativeSession() ? session : createSessionProxy(session));
return action.doInHibernate(sessionToExpose);
}**
发现这个doExcute方法里的一个参数enforceNativeSession
,它会决定是否代理session,导致session强制转换SessionImplementor的时候出错。在execute();这个里面已经将他的值设为了false也就是说这个这个没法解决了吗,当然不是,HibernateTemplate这个模板中还有个方法executeWithNativeSession()我们来看一看它的方法体
public <T> T executeWithNativeSession(HibernateCallback<T> action) {
return doExecute(action, true);
}
所以到这问题就已经解决了我们将getHibernateTemplate().execute()换成getHibernateTemplate().executeWithNativeSession()就行了