在Hibernate / Spring 4升级后,ClassCastException Proxy36不能转换为SessionImplementor [英] ClassCastException Proxy36 cannot be cast to SessionImplementor after Hibernate/Spring 4 upgrade
问题描述
编辑:我不是问什么一个ClassCastException。我在询问在Spring 4 / Hibernate 4的特定配置下DetachedCriteria中是什么导致它的。
我试图将一些遗留代码升级到Spring 4 / Hibernate 4和我碰到了一堵墙,因为谷歌并没有太多兴趣。
我试图在一个非常简单的Hibernate仓库上运行JUnit测试,并且它失败了。
java.lang.ClassCastException:com.sun.proxy。$ Proxy36不能转换为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
class:
/ **
*获取Criteria的可执行实例以实际运行查询。
*
* @param session将构建的Criteria与
*
* @return关联的会话可执行文件标准
* /
public Criteria getExecutableCriteria(Session session){
impl.setSession((SessionImplementor)session);
返回impl;
}
当它试图设置会话(试图将其转换为SessionImplementor ),它抛出ClassCastException。
我怀疑这可能是AOP问题,但不知道从哪里开始寻找。
我使用Spring 4.3.2.RELEASE
和Hibernate 4.3.5.Final
。
< bean id = xxxSessionFactoryclass =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =xxxDataSource/>
< property name =mappingResources>
< list>
< value> hibernate / xxxUploadDocResponseInfo.hbm.xml< / value>
< / list>
< / property>
< property name =hibernateProperties>
<道具>
< 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>
< /道具>
< / property>
< alias name =xxxSessionFactoryalias =sessionFactory/>
< / bean>
transaction-context.xml:
< bean id =xxxTransactionManagerclass =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>
< tx:advice id =xxxTxAdvicetransaction-manager =xxxDatasourceTransactionManager>
< tx:attributes>
< tx:method name =*propagation =REQUIRED/>
<! - 所有方法都以save保存事务 - >
< 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:方法名称=get *只读=true/>
< tx:method name =flag *只读=true/>
< tx:method name =doWork *propagation =REQUIRES_NEW/>
< / tx:属性>
< / tx:advice>
< bean id =xxxDatasourceTransactionManagerclass =org.springframework.jdbc.datasource.DataSourceTransactionManager>
< constructor-arg ref =xxxDataSource/>
< / bean>
< aop:config>
< / aop:config>
AbstractHibernateRepository.java:
public abstract class AbstractHibernateRepository< E extends Entity,S extends Serializable>扩展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();
}
});
}
...
}
请参阅 HibernateTemplate#doExecute
$ b
enforceNativeSession
- 是否强制本机Hibernate Session暴露给回调代码
正如您在< a href =http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-orm/4.0.2.RELEASE/org/springframework/orm/hibernate4/HibernateTemplate.java#HibernateTemplate。
<$ c $ session_getClass()。getClassLoader(),new Cla() ss<> [] {Session.class},
new CloseSuppressingInvocationHandler(session));
}
创建的代理仅实现接口 Session
不是接口 SessionImplementor
。
您必须将 HibernateTemplate#执行与 HibernateTemplate#executeWithNativeSession 。
EDIT: I am not asking what a ClassCastException is. I am asking what is causing it in DetachedCriteria under this specific configuration of Spring 4/Hibernate 4.
I'm trying to upgrade some legacy code to Spring 4/Hibernate 4 and I've hit a wall, as Google isn't turning up much.
I am trying to run a JUnit test on a very simple Hibernate repository, and it is failing with
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)
...
This is happening in Hibernate's org.hibernate.criterion.DetachedCriteria
class:
/**
* 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;
}
When it tries to set the Session (which attempts to cast it to a SessionImplementor), it throws the ClassCastException.
I suspect this may be an AOP issue, but am not sure where to start looking.
I'm using Spring 4.3.2.RELEASE
, and Hibernate 4.3.5.Final
.
hibernate-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>
transaction-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();
}
});
}
...
}
See HibernateTemplate#doExecute
enforceNativeSession
- whether to enforce exposure of the native Hibernate Session to callback code
As you can see at GrepCode:
protected Session createSessionProxy(Session session) { return (Session) Proxy.newProxyInstance( session.getClass().getClassLoader(), new Class<?>[] {Session.class}, new CloseSuppressingInvocationHandler(session)); }
the created proxy implements only the interface Session
not the interface SessionImplementor
.
You have to replace HibernateTemplate#execute with HibernateTemplate#executeWithNativeSession.
这篇关于在Hibernate / Spring 4升级后,ClassCastException Proxy36不能转换为SessionImplementor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!