2016-08-13 42 views
2

編輯:我不是要求什麼是 ClassCastException是。我在問這是什麼導致它在DetachedCriteria在Spring 4/Hibernate 4的這個特定配置下。ClassCastException在Hibernate/Spring 4升級後,Proxy36不能轉換爲SessionImplementor

我想升級一些遺留代碼到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; 
} 

當它試圖設置會話(試圖將其轉換爲SessionImplementor),它會引發ClassCastException。

我懷疑這可能是一個AOP問題,但我不確定從哪裏開始尋找。

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

休眠-context.xml中:

<bean id="xxxSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 

     <property name="dataSource" ref="xxxDataSource" /> 

     <property name="mappingResources"> 
      <list> 
       <value>hibernate/xxxUploadDocResponseInfo.hbm.xml</value> 
      </list> 
     </property> 

     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${xxx.hibernate.dialect}</prop> 
       <prop key="hibernate.show_sql">${xxx.hibernate.showsql}</prop> 
       <prop key="hibernate.hbm2ddl.auto">${xxx.hibernate.hbm2ddl}</prop> 
       <prop key="format_sql">${xxx.hibernate.formatsql}</prop> 
       <prop key="hibernate.query.substitutions">true 1, false 0</prop> 

      </props> 
     </property> 
    <alias name="xxxSessionFactory" alias="sessionFactory" /> 
</bean> 

事務的context.xml:

<bean id="xxxTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<tx:advice id="xxxTxAdvice" transaction-manager="xxxDatasourceTransactionManager"> 
    <tx:attributes> 
     <tx:method name="*" propagation="REQUIRED" /> 
     <!-- all methods begin with save have the transaction --> 
     <tx:method name="save*" propagation="REQUIRED"/> 
     <tx:method name="add*" propagation="REQUIRED"/> 
     <tx:method name="update*" propagation="REQUIRED"/> 
     <tx:method name="remove*" propagation="REQUIRED"/> 
     <tx:method name="inactivate*" propagation="REQUIRED"/> 
     <tx:method name="complete*" propagation="REQUIRED"/> 
     <tx:method name="reset*" propagation="REQUIRED"/> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="flag*" read-only="true"/> 
     <tx:method name="doWork*" propagation="REQUIRES_NEW" /> 
    </tx:attributes> 
</tx:advice> 

<bean id="xxxDatasourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <constructor-arg ref="xxxDataSource" /> 
</bean> 

<aop:config> 
    <aop:pointcut id="allBusiness" expression="execution(public * com.blah.xxx.rest.business.*Business.*(..))"/> 
    <aop:advisor advice-ref="xxxTxAdvice" pointcut-ref="allBusiness"/> 
</aop:config> 

AbstractHibernateRepository.java:

public abstract class AbstractHibernateRepository<E extends Entity, S extends Serializable> extends HibernateDaoSupport { 
... 
     @SuppressWarnings("unchecked") 
protected E get(final DetachedCriteria detachedCriteria) { 
    return (E) getHibernateTemplate().execute(new HibernateCallback<E>() { 

     public E doInHibernate(Session session) { 

      Criteria criteria = detachedCriteria.getExecutableCriteria(session); 
      criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 
      return (E) criteria.uniqueResult(); 
     } 
    }); 
} 
... 
} 

回答

1

HibernateTemplate#doExecute

enforceNativeSession - 是否強制本地Hibernate的Session暴露於回調代碼

正如你可以在GrepCode看到:

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

創建的代理只實現接口Session不界面SessionImplementor

您必須將HibernateTemplate#execute替換爲HibernateTemplate#executeWithNativeSession

+0

令人驚歎。我知道它必須是一攬子的。非常感謝您的耐心。 – bdetweiler

相關問題