spring-data-jpa
spring-data-jpa copied to clipboard
CrudMethodMetadataPostProcessor.java:153 throws a ClassCastException in a project with multiple Spring Data modules
I have a project that includes both Spring Data modules; spring-data-jpa and spring-data-couchbase.
When I try to save an entity using a JPA repository the following class:
https://github.com/spring-projects/spring-data-jpa/blob/2.6.x/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java
throws a ClassCastException at line 153.
LOG INFORMATION: java.lang.ClassCastException: class org.springframework.data.couchbase.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata cannot be cast to class org.springframework.data.jpa.repository.support.CrudMethodMetadata (org.springframework.data.couchbase.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata and org.springframework.data.jpa.repository.support.CrudMethodMetadata are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @23aae55) at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:153) ~[spring-data-jpa-2.6.4.jar:2.6.4]
I noticed that the class DefaultCrudMethodMetadata lives in both Spring Data modules.
JPA (spring-data-jpa 2.6.4) https://github.com/spring-projects/spring-data-jpa/blob/2.6.x/src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java at line 190
COUCHBASE (spring-data-couchbase 4.3.4) https://github.com/spring-projects/spring-data-couchbase/blob/4.3.x/src/main/java/org/springframework/data/couchbase/repository/support/CrudMethodMetadataPostProcessor.java at line 185
It looks like the jpa data module is picking the wrong class to be casted when multiple Spring Data Modules exist in a project. The question is, why is the jpa module picking the Couchbase DefaultCrudMethodMetadata class for casting?
If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Unfortunately, I cannot share the project for security purposes and I couldn't duplicate the issue in a minimal sample neither.
However, I noticed that "downgrading" or changing the version of the spring-data-couchbase jar from "4.3.4" to "4.2.11" solved the problem.
In the newer version, something is making the TransactionSynchronizationManager to bind a CrudRepository.save method to a Couchbase resource "org.springframework.data.couchbase.repository.support.CrudMethodMetadataPostProcessor$DefaultCrudMethodMetadata"

My repository extends the JpaRepository component and the associated entity class has the @Entity annotation (javax.persistance.Entity).
I'm not sure why is picking a Couchbase resource instead when I try to save the entity in the database.
I was able to duplicate the issue. Please find the minimal sample project at this link
It uses an in-memory database for the JPA repository.
The only configuration needed is a Couchbase server for the Couchbase repository.
This project creates a war file that can be deployed in a tomcat server and starts listening for requests at the /demo/entries endpoint.
Once this endpoint is hit, it produces the issue. The main code that duplicates the problem can be found at the DemoController.java class.