ClassCastException with spring-data-jpa

366 Views Asked by At

I'm working with Spring Web Services and Spring JPA Data.

I have three projects:

  • doc-ws. Web application that it's the endpoint of my documental web services.
  • sign-ws. Web application that it's the endpoint of my sign web services.
  • data-ws. Jar module with all the jpa entities (@Entity), spring jpa repositories (@Repository) and spring services classes (@Services).

Doc-ws and sign-ws has a dependence with data-ws, so a data-ws.jar is included in doc-ws.war and sign-ws.war.

When I deploy doc-ws web application alone, all the web services tests works fine. When I deploy sign-ws web application alone, all the web services tests works fine. But when I deploy both web applications together in the same Jboss EAP 7.1, I'm getting ClassCastExceptions when I exectute the web services tests.

java.lang.ClassCastException: com.ieci.mugeju.data.entity.IdocConfiguration cannot be cast to com.ieci.mugeju.data.entity.IdocConfiguration

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

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

Exception message reference the same jpa entity (com.ieci.mugeju.data.entity.IdocConfiguration), so I don't understand why this exception is being throwed.

It must be a classloading issue between both web applications, but I'm not sure.

I'm working with JBoss EAP 7.1, spring-data-jpa 2.0.5, eclipseling 2.6.4, spring-ws-core 3.0.1.

Any idea why I'm getting this exception? How could I solve?

Thanks

1

There are 1 best solutions below

0
On BEST ANSWER

I discovered what the problem was. When I defined the 'entityManagerFactory', I was not setting the property called 'persistenceUnitName'. Then when the persistence context was created, it was created with the name 'default' in both web projects.

<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>

I don't know why but 'find repository methods' of second project return jpa entity classes defined in first project classloader. Very strange behaviour, I expected every web application using its own classloader, and isolated one from each other.

If I set a persistenceUnitName for every project, then everything works fine, and every web application uses its own classloader.

<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>