Description
Since the auto indexes were set to false by default, creating the indexes programmatically on a spring application causes indexes to be created wrong.
It seems the cause for this is a fix for spring-data-mongodb in versions 3 and up [https://github.com/spring-projects/spring-data-mongodb/commit/ab5b1f01409b301483a0692a9417522731ce40a5]
mapper.getMappedSort call leads to collection.createIndex parameter to be wrong for some of our indexes
and leads to errors like
{ v: 2, key: { interactionElements.conditions.name: 1 }, name: "interactionElements.conditions.name", has the same name as the requested index: { v: 2, key: { interactionElements.conditions.conditions.name: 1 }
Note the redundant '.conditions' in the request.
This occurs when one of the parameters is a map.
The problem is severe - we cannot trust Spring Data with programmatic indexes creation from Java.
`
private void ensureAnnotatedIndexes(MongoConnection connection, String tenantId, String environmentName) {
try {
log.debug("Going to ensure annotated indexes for {}, {}", tenantId, environmentName);
MongoTemplate tenantEnvMongoTemplate = connection.mongoTemplate;
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext = tenantEnvMongoTemplate.getConverter().getMappingContext();
IndexResolver resolver = new MongoPersistentEntityIndexResolver(mappingContext);
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Document.class));
for (BeanDefinition bd : scanner.findCandidateComponents(BASE_PACKAGE_FOR_ANNOTATED_INDEXED_ENTITIES)) {
String documentClassName = bd.getBeanClassName();
try {
Class<?> documentClass = Class.forName(documentClassName);
log.trace("Going to ensure annotated indexes for {}, {}, {}", documentClassName, tenantId, environmentName);
Iterable<? extends IndexDefinition> indexes = resolver.resolveIndexFor(documentClass);
if (!indexes.iterator().hasNext()) {
log.trace("No annotated indexes found for {}, {}, {}", documentClassName, tenantId, environmentName);
continue;
}
IndexOperations indexOps = tenantEnvMongoTemplate.indexOps(documentClass);
indexes.forEach(indexOps::ensureIndex);
log.debug("Done ensuring indexes for {}, {}, {}", documentClassName, tenantId, environmentName);
} catch (Exception e) {
log.error("Error while trying to ensure indexes for {}, {}, {}", documentClassName, tenantId, environmentName, e);
}
}
log.info("Done with ensurement of annotated indexes for {}, {}", tenantId, environmentName);
} catch (Exception e) {
log.error("Failed to ensure indexes for {}, {}", tenantId, environmentName, e);
}
}
}`