spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.

Home Page:https://spring.io/projects/spring-data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Spring-Data-Commons Upgrade is causing MongoDB driver to throw CodecConfigurationException

Raghav-Murali opened this issue · comments

Issue Description

I'm currently in the process of upgrading several libraries in my project:

  • org.mongodb:mongodb-driver-legacy:4.6.1 to 4.8.2
  • org.mongodb:mongodb-driver-sync:4.6.1 to 4.8.2
  • org.mongodb:mongodb-driver-core:4.6.1 to 4.8.2
  • org.mongodb:bson:4.6.1 to 4.8.2
  • org.springframework.data:spring-data-commons:2.7.7 to 3.0.6
  • org.springframework.data:spring-data-mongodb:3.4.7 to 4.0.6
  • org.springframework:spring-aop:5.3.27 to 6.0.9
  • org.springframework:spring-beans:5.3.27 to 6.0.9
  • org.springframework:spring-context:5.3.27 to 6.0.9
  • org.springframework:spring-core:5.3.27 to 6.0.9
  • org.springframework:spring-expression:5.3.27 to 6.0.9
  • org.springframework:spring-jcl:5.3.27 to 6.0.9
  • org.springframework:spring-messaging:5.3.27 to 6.0.9
  • org.springframework:spring-test:5.3.27 to 6.0.9
  • org.springframework:spring-tx:5.3.27 to 6.0.9
  • org.springframework:spring-web:5.3.27 to 6.0.9

I've attempted this upgrade with both MongoDB server versions 5.0 and 6.0, as the MongoDB driver release page suggests using MongoDB server version 6.0 for Driver version 4.8. However, I'm still encountering issues.

Scenario

Our use case involves the following scenario:

class Field<T> {
  private T value;
}

class Example1 {
  Field<ClassMapping_T_1> store;
}

// One of the classes we use in Field<T>
class ClassMapping_T_1 {
  Config config; // This is an interface
}

// One of the classes we use in Field<T>
class ClassMapping_T_2 {
  String selector;
  String origin;
}

interface Config {
  // Few methods that will be overridden by several other classes
}

class ClassImplementing_Config_1 implements Config {
  String uid; 
  Field<List<String>> files;  // This is what is causing the exception
}

We have a generics class Field<T>, where T can map to over 100 other classes, and these classes can internally also have Field<T>.

Issue

In the above scenario, we've observed that spring-data-commons is mapping Field<List<String>> to Field<ClassMapping_T_2> and creating a MongoDB BSON Document object that contains Field<ClassMapping_T_2> instead of Field<List<String>>. When this Document reaches the MongoDB driver, it complains that a Codec is not found for Field<ClassMapping_T_2, resulting in a CodecConfigurationException.

Upon further debugging, we noticed that the issue arises in the spring-data-commons library's AbstractMappingContext class. Before the upgrade, the persistentEntities map in AbstractMappingContext had over 2500 entries, whereas after the upgrade, it had roughly 1900 entries.

Before the library upgrade, we observed that AbstractMappingContext had the mapping for Field<List<String>>. After the upgrade, however, it didn't have any mappings for Field<List<String>>, but it did have a mapping for Field<ClassMapping_T_2>. Consequently, spring-data-commons mapped Field<List<String>> to the entity of Field<ClassMapping_T_2>, creating a wrongly wired MongoDB BSON Document object. When this document is given to the MongoDB driver, it complains that there is no Codec found for ClassMapping_T_2, resulting in a CodecConfigurationException.

AbstractMappingContext creates all the mapping contexts through Guice. We tried upgrading org.springframework.guice:spring-guice, which is the bridge from com.google.inject:guice, but had no luck with it.

Request for Assistance

Could any Spring Framework subject matter experts or contributors kindly assist with this issue?

Sounds like a duplicate of #3051

@mp911de - When will the release 3.1.10 which has the fix for this be available publicly in Maven ?