HibernateTemplate 在Spring2.5以前 有兩個 execute 方法:
1.execute(HibernateCallback action)
2.execute(HibernateCallback action, boolean enforceNativeSession)
區別如下:
spring的HibernateTemplate的execute方法提供的回調接口具有Session作爲參數,但是實際上,默認情況下,HibernateTemplate傳遞給回調接口的session並不是org.hibernate.impl.SessionImpl類,而是SessionImpl類的一個Proxy類。之所以替換成爲一個Proxy類,HibernateTemplate的註釋說明,Proxy提供了一些額外的功能,包括自動設置Cachable,Transaction的超時時間,Session資源的更積極的關閉等等。
java代碼:
private boolean exposeNativeSession = false;
...
execute方法內部:
Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy(session));
但是遺憾的是,Hibernate的DetachedCriteria的setExecutableCriteria方法卻要求將session參數強制轉爲SessionImpl,但是spring傳過來的卻是一個Proxy類,因此就報錯了。
java代碼:
public Criteria getExecutableCriteria(Session session) {
impl.setSession( (SessionImpl) session ); // 要求SessionImpl,Spring傳遞的是Proxy
return impl;
}
解決方法,禁止Spring的HibernateTemplate傳遞Proxy類,強制要求它傳遞真實的SessionImpl類,即給exexute方法增加一個參數,提供參數爲true,如下:
java代碼:
public List findByCriteria(final DetachedCriteria detachedCriteria) {
return (List) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
return criteria.list();
}
}, true);
}
在Spring2.5以後的HibernateTemplate中,第二個execute方法已經Deprecated了,被executeWithNativeSession
方法取代