Closed
Description
We updated from spring boot 2.4.2 to 2.5.0, and now Index creation is broken. This means the same code that worked before wont under 2.5.0. (spring-data-mongodb 3.1.3
to 3.2.1
)
I have created a sample Project which shows the problem: https://gitlab.com/elderbyte/public/examples/spring-mongo-index-issue
Creating an mongo index fails, when the dot path notation is used and the referenced class is in a separate library has a custom mongo converter:
@Configuration
@EnableMongoRepositories()
public class DefaultMongoConfiguration {
@Bean
public MongoCustomConversions customConversions(){
var converters = new ArrayList<Converter<?,?>>();
converters.add(new MyAddressToDocumentConverter()); // Comment this out, and it works
return new MongoCustomConversions(converters);
}
@WritingConverter
public static class MyAddressToDocumentConverter implements Converter<MyAddress, Document> {
@Override
public Document convert(MyAddress address) {
var doc = new Document();
doc.put("street", address.getStreet());
return doc;
}
}
}
The entity for which this index is being defined looks like this (simplified):
@Document
public class Customer {
@Id
private ObjectId id;
private String name;
private MyAddress address;
}
public class MyAddress {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
Creating an Index via ensure index yields an unexpected exception:
indexOps.ensureIndex(
TextIndexDefinition
.builder()
.named("TextIndex")
.onField("name")
.onField("address.street")
.build()
);
Stacktrace
org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for property private com.elderbyte.starter.demo.domain.customers.MyAddress com.elderbyte.starter.demo.domain.customers.Customer.address!
at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:152) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPair(PersistentPropertyPathFactory.java:225) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:199) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$1(PersistentPropertyPathFactory.java:172) ~[spring-data-commons-2.5.1.jar:2.5.1]
at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:171) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:86) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:99) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:285) ~[spring-data-commons-2.5.1.jar:2.5.1]
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:1183) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1045) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1022) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.convert.QueryMapper.createPropertyField(QueryMapper.java:329) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedSort(QueryMapper.java:197) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.DefaultIndexOperations.lambda$ensureIndex$0(DefaultIndexOperations.java:130) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:539) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.DefaultIndexOperations.execute(DefaultIndexOperations.java:211) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at org.springframework.data.mongodb.core.DefaultIndexOperations.ensureIndex(DefaultIndexOperations.java:121) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
at com.elderbyte.starter.demo.domain.customers.CustomerIndexConfiguration.initIndicesAfterStartup(CustomerIndexConfiguration.java:54) ~[main/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.7.jar:5.3.7]
at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
at org.springframework.boot.SpringApplicationRunListeners.lambda$running$6(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) ~[spring-boot-2.5.0.jar:2.5.0]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:352) ~[spring-boot-2.5.0.jar:2.5.0]
at com.elderbyte.starter.demo.MongodbDemoServer.main(MongodbDemoServer.java:21) ~[main/:na]
2021-05-27 10:59:59.330 INFO 9895 --- [ main] o.s.b.a.ApplicationAvailabilityBean : Application availability state ReadinessState changed to REFUSING_TRAFFIC
2021-05-27 10:59:59.358 INFO 9895 --- [ main] org.mongodb.driver.connection : Closed connection [connectionId{localValue:3, serverValue:840}] to localhost:27017 because the pool has been closed.
Process finished with exit code 1
Conclusions:
- We observed the problem first with Spring Boot 2.5.0 which uses the version
3.2.1
of spring-data-mongodb- Therefore it looks like a regression from Spring Boot
2.4.2
where the same code works (3.1.3
of spring-data-mongodb) - Edit: Spring Boot
2.4.6
also works (3.1.9 spring-data-mongodb)
- Therefore it looks like a regression from Spring Boot
The classcom.elderbyte.commons.i18n.I18nText
is in another library which is a gradle (maven) dependency.Repository Base package has been set tocom.elderbyte
so it should include both classesIf I copy the class from that library into the local project, it works.- It seems to be caused by the custom converter.
- If the custom converter is not registered, it works.
Any idea what could have caused this and how to fix it?