ClassCastException在Hibernate / Spring 4升级后,无法将Proxy36强制转换为SessionImplementor

编辑:我不是在问ClassCastException是什么 我问在Spring 4 / Hibernate 4的这个特定配置下DetachedCriteria中是什么导致它。

我正在尝试将一些遗留代码升级到Spring 4 / Hibernate 4,而且我已经碰壁了,因为Google并没有出现太多问题。

我试图在一个非常简单的Hibernate存储库上运行JUnit测试,但它失败了

java.lang.ClassCastException: com.sun.proxy.$Proxy36 cannot be cast to org.hibernate.engine.spi.SessionImplementor at org.hibernate.criterion.DetachedCriteria.getExecutableCriteria(DetachedCriteria.java:84) at com.my.app.rest.domain.repository.AbstractHibernateRepository$6.doInHibernate(AbstractHibernateRepository.java:163) ... 

这发生在Hibernate的org.hibernate.criterion.DetachedCriteria类中:

 /** * Get an executable instance of Criteria to actually run the query. * * @param session The session to associate the built Criteria with * * @return The "executable" Criteria */ public Criteria getExecutableCriteria(Session session) { impl.setSession( (SessionImplementor) session ); return impl; } 

当它尝试设置Session(尝试将其转换为SessionImplementor)时,它会抛出ClassCastException。

我怀疑这可能是一个AOP问题,但我不知道从哪里开始寻找。

我正在使用Spring 4.3.2.RELEASE和Hibernate 4.3.5.Final

hibernate-context.xml中:

      hibernate/xxxUploadDocResponseInfo.hbm.xml     ${xxx.hibernate.dialect} ${xxx.hibernate.showsql} ${xxx.hibernate.hbm2ddl} ${xxx.hibernate.formatsql} true 1, false 0     

交易context.xml中:

                           

AbstractHibernateRepository.java:

 public abstract class AbstractHibernateRepository extends HibernateDaoSupport { ... @SuppressWarnings("unchecked") protected E get(final DetachedCriteria detachedCriteria) { return (E) getHibernateTemplate().execute(new HibernateCallback() { public E doInHibernate(Session session) { Criteria criteria = detachedCriteria.getExecutableCriteria(session); criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); return (E) criteria.uniqueResult(); } }); } ... } 

请参阅HibernateTemplate#doExecute

enforceNativeSession – 是否强制将本机Hibernate会话暴露给回调代码

正如您在GrepCode中看到的:

 protected Session createSessionProxy(Session session) { return (Session) Proxy.newProxyInstance( session.getClass().getClassLoader(), new Class[] {Session.class}, new CloseSuppressingInvocationHandler(session)); } 

创建的代理只实现接口Session而不是SessionImplementor接口。

你必须用HibernateTemplate #cuteWithNativeSession替换HibernateTemplate#execute 。