首页 > 解决方案 > 带有 spring-data-jpa 的 ClassCastException

问题描述

我正在使用 Spring Web Services 和 Spring JPA Data。

我有三个项目:

doc-ws 和 sign-ws 与 data-ws 有依赖关系,所以 doc-ws.war 和 sign-ws.war 中包含了一个 data-ws.jar。

当我单独部署 doc-ws Web 应用程序时,所有 Web 服务测试都可以正常工作。当我单独部署 sign-ws Web 应用程序时,所有 Web 服务测试都可以正常工作。但是,当我在同一个 Jboss EAP 7.1 中同时部署这两个 Web 应用程序时,我在执行 Web 服务测试时遇到了 ClassCastExceptions。

java.lang.ClassCastException:com.ieci.mugeju.data.entity.IdocConfiguration 无法转换为 com.ieci.mugeju.data.entity.IdocConfiguration

    List<IdocConfiguration> properties = idocConfigurationRepository.findAll();   <-- works fine

    for (IdocConfiguration property: properties)    <-- Here throws the ClassCastException
    {
       .... // CODE
    }

异常消息引用了同一个 jpa 实体(com.ieci.mugeju.data.entity.IdocConfiguration),所以我不明白为什么会抛出这个异常。

这一定是两个 Web 应用程序之间的类加载问题,但我不确定。

我正在使用 JBoss EAP 7.1、spring-data-jpa 2.0.5、eclipseling 2.6.4、spring-ws-core 3.0.1。

知道为什么我会收到此异常吗?我该怎么解决?

谢谢

标签: jbossspring-data-jpaclasscastexceptionspring-wsclassloading

解决方案


我发现了问题所在。当我定义“entityManagerFactory”时,我没有设置名为“persistenceUnitName”的属性。然后,当创建持久性上下文时,它在两个 Web 项目中都使用名称“default”创建。

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaAdapter" />
    <property name="jpaDialect" ref="jpaDialect"/>      
    <property name="packagesToScan" value="com.ieci.mugeju.data.entity" />              
    ...
</bean>

我不知道为什么,但第二个项目的“查找存储库方法”返回第一个项目类加载器中定义的 jpa 实体类。非常奇怪的行为,我希望每个 Web 应用程序都使用自己的类加载器,并且彼此隔离。

如果我为每个项目设置一个 persistenceUnitName,那么一切正常,每个 Web 应用程序都使用自己的类加载器。

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaAdapter" />
    <property name="jpaDialect" ref="jpaDialect"/>      
    <property name="packagesToScan" value="com.ieci.mugeju.data.entity" />      
    <property name="persistenceUnitName" value="${spring.application.name}" />
    ...
</bean>

推荐阅读