简体   繁体   English

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

[英]ClassCastException Proxy36 cannot be cast to SessionImplementor after Hibernate/Spring 4 upgrade

EDIT: I am not asking what a ClassCastException is.编辑:我不是在问 ClassCastException 是什么 I am asking what is causing it in DetachedCriteria under this specific configuration of Spring 4/Hibernate 4.我在问在 Spring 4/Hibernate 4 的这个特定配置下是什么导致它在 DetachedCriteria 中。

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.我正在尝试将一些遗留代码升级到 Spring 4/Hibernate 4,但我遇到了困难,因为 Google 并没有出现太多问题。

I am trying to run a JUnit test on a very simple Hibernate repository, and it is failing with我正在尝试在一个非常简单的 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)
...

This is happening in Hibernate's org.hibernate.criterion.DetachedCriteria class:这发生在 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;
}

When it tries to set the Session (which attempts to cast it to a SessionImplementor), it throws the ClassCastException.当它尝试设置 Session(试图将其转换为 SessionImplementor)时,它会抛出 ClassCastException。

I suspect this may be an AOP issue, but am not sure where to start looking.我怀疑这可能是 AOP 问题,但我不确定从哪里开始寻找。

I'm using Spring 4.3.2.RELEASE , and Hibernate 4.3.5.Final .我正在使用 Spring 4.3.2.RELEASE和 Hibernate 4.3.5.Final

hibernate-context.xml:休眠上下文.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:事务上下文.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: 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();
        }
    });
}
...
}

Faced same issue on legacy code after upgrade to spring boot 2.4.0.升级到 spring boot 2.4.0 后,在遗留代码上遇到了同样的问题。 Fixed by using entityManager.unwrap(SessionImplementor.class) to retrieve the session to be used for DetachedCriteria in my scenario.在我的场景中,通过使用entityManager.unwrap(SessionImplementor.class)检索要用于 DetachedCriteria 的会话来修复。

See HibernateTemplate#doExecuteHibernateTemplate#doExecute

enforceNativeSession - whether to enforce exposure of the native Hibernate Session to callback code enforceNativeSession -是否强制本地Hibernate的Session暴露于回调代码

As you can see at GrepCode :正如您在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 .创建的代理仅实现接口Session而不是接口SessionImplementor

You have to replace HibernateTemplate#execute with HibernateTemplate#executeWithNativeSession .你必须用HibernateTemplate#executeWithNativeSession替换HibernateTemplate#execute

如果有人在FullTextEntityManager遇到此问题,@Gardella 的答案有效,但是,此链接建议将 Hibernate Search ORM 依赖项更新为 5.11.6.Final,这也解决了该问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hibernate 5 Javassist ClassCastException:无法转换为 javassist.util.proxy.Proxy - Hibernate 5 Javassist ClassCastException: cannot be cast to javassist.util.proxy.Proxy Hibernate ClassCastException IdentNode无法转换为DotNode - Hibernate ClassCastException IdentNode cannot cast to DotNode ClassCastException $ Proxy无法转换为使用aop - ClassCastException $Proxy cannot be cast to using aop ClassCastException HikariCPConnectionProvider无法强制转换为Hibernate ConnectionProvider - ClassCastException HikariCPConnectionProvider cannot be cast to Hibernate ConnectionProvider OSGI和Spring异常:引起:java.lang.ClassCastException:$ Proxy17无法强制转换为 - OSGI & Spring Exception: Caused by: java.lang.ClassCastException: $Proxy17 cannot be cast to ClassCastException:Proxy0无法强制转换为interfaces.Patient - ClassCastException : Proxy0 cannot be cast to interfaces.Patient java.lang.ClassCastException:$ Proxy99无法强制转换 - java.lang.ClassCastException: $Proxy99 cannot be cast ClassCastException:com.sun.proxy.$ProxyX 无法转换为类 - ClassCastException: com.sun.proxy.$ProxyX cannot be cast to a class 无法将 ClassCastException 对象强制转换为 - ClassCastException Object cannot be cast to Hibernate ClassCastException org.hibernate.type.SerializableType 不能转换为 org.hibernate.type.VersionType - Hibernate ClassCastException org.hibernate.type.SerializableType cannot be cast to org.hibernate.type.VersionType
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM