From e7333a9c50a38e746edf3c9030d83a846d08746e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 16 Jan 2019 13:46:38 +0100 Subject: [PATCH 1/5] DATAMONGO-2188 - Prepare issue branch. --- pom.xml | 2 +- spring-data-mongodb-benchmarks/pom.xml | 2 +- spring-data-mongodb-cross-store/pom.xml | 4 ++-- spring-data-mongodb-distribution/pom.xml | 2 +- spring-data-mongodb/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 657607148e..7aad355338 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml index c2ff37b35c..fcbec2ec6b 100644 --- a/spring-data-mongodb-benchmarks/pom.xml +++ b/spring-data-mongodb-benchmarks/pom.xml @@ -7,7 +7,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml index fd36f227c0..6d93c83777 100644 --- a/spring-data-mongodb-cross-store/pom.xml +++ b/spring-data-mongodb-cross-store/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT ../pom.xml @@ -50,7 +50,7 @@ org.springframework.data spring-data-mongodb - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index fc8d28a2b6..4ce4ddb459 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index f3c85a046a..cbe8c93229 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2188-SNAPSHOT ../pom.xml From 76e7d297f1f312aa4ac8a8858a20b4d6e3154912 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 16 Jan 2019 14:04:12 +0100 Subject: [PATCH 2/5] DATAMONGO-2188 - Deprecate auto-index creation. --- .../data/mongodb/core/index/CompoundIndex.java | 12 ++++++++---- .../data/mongodb/core/index/IndexResolver.java | 4 ++-- .../data/mongodb/core/index/Indexed.java | 17 +++++++++++------ .../core/index/MongoMappingEventPublisher.java | 2 ++ .../MongoPersistentEntityIndexCreator.java | 14 ++++++++------ .../IndexEnsuringQueryCreationListener.java | 3 +++ src/main/asciidoc/reference/mapping.adoc | 2 +- 7 files changed, 35 insertions(+), 19 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java index 3395da3bd5..2cac65a39b 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/CompoundIndex.java @@ -55,7 +55,8 @@ /** * @return - * @see https://docs.mongodb.org/manual/core/index-unique/ + * @see https://docs.mongodb.org/manual/core/index-unique/ */ boolean unique() default false; @@ -63,13 +64,15 @@ * If set to true index will skip over any document that is missing the indexed field. * * @return - * @see https://docs.mongodb.org/manual/core/index-sparse/ + * @see https://docs.mongodb.org/manual/core/index-sparse/ */ boolean sparse() default false; /** * @return - * @see https://docs.mongodb.org/manual/core/index-creation/#index-creation-duplicate-dropping + * @see https://docs.mongodb.org/manual/core/index-creation/#index-creation-duplicate-dropping * @deprecated since 2.1. No longer supported by MongoDB as of server version 3.0. */ @Deprecated @@ -131,7 +134,8 @@ * If {@literal true} the index will be created in the background. * * @return - * @see https://docs.mongodb.org/manual/core/indexes/#background-construction + * @see https://docs.mongodb.org/manual/core/indexes/#background-construction */ boolean background() default false; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java index c1c87ea2a8..f2765c2465 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java @@ -28,8 +28,8 @@ interface IndexResolver { /** - * Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s are created - * for properties and types with {@link Indexed}, {@link CompoundIndexes} or {@link GeoSpatialIndexed}. + * Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s + * are created for properties and types with {@link Indexed}, {@link CompoundIndexes} or {@link GeoSpatialIndexed}. * * @param typeInformation * @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java index 5ecb62d200..d0b2535346 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/Indexed.java @@ -31,7 +31,7 @@ * @author Christoph Strobl * @author Jordi Llach */ -@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD}) +@Target({ ElementType.ANNOTATION_TYPE, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface Indexed { @@ -39,7 +39,8 @@ * If set to true reject all documents that contain a duplicate value for the indexed field. * * @return - * @see https://docs.mongodb.org/manual/core/index-unique/ + * @see https://docs.mongodb.org/manual/core/index-unique/ */ boolean unique() default false; @@ -49,13 +50,15 @@ * If set to true index will skip over any document that is missing the indexed field. * * @return - * @see https://docs.mongodb.org/manual/core/index-sparse/ + * @see https://docs.mongodb.org/manual/core/index-sparse/ */ boolean sparse() default false; /** * @return - * @see https://docs.mongodb.org/manual/core/index-creation/#index-creation-duplicate-dropping + * @see https://docs.mongodb.org/manual/core/index-creation/#index-creation-duplicate-dropping * @deprecated since 2.1. No longer supported by MongoDB as of server version 3.0. */ @Deprecated @@ -115,7 +118,8 @@ * If {@literal true} the index will be created in the background. * * @return - * @see https://docs.mongodb.org/manual/core/indexes/#background-construction + * @see https://docs.mongodb.org/manual/core/indexes/#background-construction */ boolean background() default false; @@ -123,7 +127,8 @@ * Configures the number of seconds after which the collection should expire. Defaults to -1 for no expiry. * * @return - * @see https://docs.mongodb.org/manual/tutorial/expire-data/ + * @see https://docs.mongodb.org/manual/tutorial/expire-data/ */ int expireAfterSeconds() default -1; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java index 0c8fdb415f..6bba8eb8f2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java @@ -36,7 +36,9 @@ * @author Jon Brisbin * @author Oliver Gierke * @author Mark Paluch + * @deprecated since 2.2. Use {@link IndexOperations} to define and create indexes. */ +@Deprecated public class MongoMappingEventPublisher implements ApplicationEventPublisher { private final ApplicationListener> indexCreator; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index c4a7f3f608..80d5966daf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -63,10 +63,12 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener { private static final Set GEOSPATIAL_TYPES = new HashSet(Arrays.asList(Type.NEAR, Type.WITHIN)); diff --git a/src/main/asciidoc/reference/mapping.adoc b/src/main/asciidoc/reference/mapping.adoc index 706d4ec070..c495b2ef25 100644 --- a/src/main/asciidoc/reference/mapping.adoc +++ b/src/main/asciidoc/reference/mapping.adoc @@ -378,7 +378,7 @@ public class Person { IMPORTANT: The `@Id` annotation tells the mapper which property you want to use for the MongoDB `_id` property, and the `@Indexed` annotation tells the mapping framework to call `createIndex(…)` on that property of your document, making searches faster. -IMPORTANT: Automatic index creation is only done for types annotated with `@Document`. +IMPORTANT: Automatic index creation is deprecated since version 2.2 because controlling the actual time of index creation is rather difficult. Index creation can be part of the application startup, happen during runtime or an out of band process. Therefore, Spring Data MongoDB backs off entirely and recommends index creation to happen either out of band or as part of the application startup using `IndexOperations`. Automatic index creation is still available and is is only done for types annotated with `@Document`. [[mapping-usage-annotations]] === Mapping Annotation Overview From aa63e4cb607588f8d180f5fe32c3ddfcf142d0bb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 16 Jan 2019 14:39:31 +0100 Subject: [PATCH 3/5] DATAMONGO-2188 - Introduce configuration to disable auto-index creation. Auto-index creation can now be disabled by setting MongoMappingContext.setAutoIndexCreation(false). This configuration prevents automatic index creation on application startup and during access to entities. Auto-index creation comes with automated collection creation. Users that rely on collection creation (e.g. if you wish to use ClientSessions or transactions) must make sure the collection exists prior to session usage. --- .../data/mongodb/core/MongoTemplate.java | 18 ++++-- .../mongodb/core/ReactiveMongoTemplate.java | 13 +++-- .../core/mapping/MongoMappingContext.java | 25 +++++++++ .../support/MongoRepositoryFactoryBean.java | 5 +- .../ReactiveMongoRepositoryFactoryBean.java | 6 +- .../core/index/IndexingIntegrationTests.java | 56 +++++++++++++------ 6 files changed, 94 insertions(+), 29 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index 13c2606e3e..94fe71d4ca 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -246,10 +246,14 @@ public MongoTemplate(MongoDbFactory mongoDbFactory, @Nullable MongoConverter mon mappingContext = this.mongoConverter.getMappingContext(); // We create indexes based on mapping events if (mappingContext instanceof MongoMappingContext) { - indexCreator = new MongoPersistentEntityIndexCreator((MongoMappingContext) mappingContext, this); - eventPublisher = new MongoMappingEventPublisher(indexCreator); - if (mappingContext instanceof ApplicationEventPublisherAware) { - ((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher); + + MongoMappingContext mappingContext = (MongoMappingContext) this.mappingContext; + + if (mappingContext.isAutoIndexCreation()) { + + indexCreator = new MongoPersistentEntityIndexCreator(mappingContext, this); + eventPublisher = new MongoMappingEventPublisher(indexCreator); + mappingContext.setApplicationEventPublisher(eventPublisher); } } } @@ -1582,7 +1586,8 @@ public UpdateResult doInCollection(MongoCollection collection) query.getCollation().map(Collation::toMongoCollation).ifPresent(opts::collation); } - Document updateObj = update instanceof MappedUpdate ? update.getUpdateObject() : updateMapper.getMappedObject(update.getUpdateObject(), entity); + Document updateObj = update instanceof MappedUpdate ? update.getUpdateObject() + : updateMapper.getMappedObject(update.getUpdateObject(), entity); if (multi && update.isIsolated() && !queryObj.containsKey("$isolated")) { queryObj.put("$isolated", 1); @@ -1617,7 +1622,8 @@ public UpdateResult doInCollection(MongoCollection collection) }); } - private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity persistentEntity, UpdateDefinition update) { + private void increaseVersionForUpdateIfNecessary(@Nullable MongoPersistentEntity persistentEntity, + UpdateDefinition update) { if (persistentEntity != null && persistentEntity.hasVersionProperty()) { String versionFieldName = persistentEntity.getRequiredVersionProperty().getFieldName(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 3e32f780b8..34901303fb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -232,12 +232,15 @@ public ReactiveMongoTemplate(ReactiveMongoDatabaseFactory mongoDatabaseFactory, if (this.mappingContext instanceof MongoMappingContext) { MongoMappingContext mongoMappingContext = (MongoMappingContext) this.mappingContext; - this.indexCreator = new ReactiveMongoPersistentEntityIndexCreator(mongoMappingContext, this::indexOps); - this.eventPublisher = new MongoMappingEventPublisher(this.indexCreatorListener); - mongoMappingContext.setApplicationEventPublisher(this.eventPublisher); - this.mappingContext.getPersistentEntities() - .forEach(entity -> onCheckForIndexes(entity, subscriptionExceptionHandler)); + if (mongoMappingContext.isAutoIndexCreation()) { + this.indexCreator = new ReactiveMongoPersistentEntityIndexCreator(mongoMappingContext, this::indexOps); + this.eventPublisher = new MongoMappingEventPublisher(this.indexCreatorListener); + + mongoMappingContext.setApplicationEventPublisher(this.eventPublisher); + this.mappingContext.getPersistentEntities() + .forEach(entity -> onCheckForIndexes(entity, subscriptionExceptionHandler)); + } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java index 49a3d5a942..b69aada3fc 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java @@ -43,6 +43,7 @@ public class MongoMappingContext extends AbstractMappingContext, S, ID exten extends RepositoryFactoryBeanSupport { private @Nullable MongoOperations operations; - private boolean createIndexesForQueryMethods = false; + @Deprecated private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; /** @@ -60,7 +60,10 @@ public void setMongoOperations(MongoOperations operations) { * Configures whether to automatically create indexes for the properties referenced in a query method. * * @param createIndexesForQueryMethods the createIndexesForQueryMethods to set + * @deprecated since 2.2. Use {@link org.springframework.data.mongodb.core.index.IndexOperations} to define and create + * indexes. */ + @Deprecated public void setCreateIndexesForQueryMethods(boolean createIndexesForQueryMethods) { this.createIndexesForQueryMethods = createIndexesForQueryMethods; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java index 277b7d6a74..c44828c0c1 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java @@ -40,7 +40,8 @@ public class ReactiveMongoRepositoryFactoryBean, S, extends RepositoryFactoryBeanSupport { private @Nullable ReactiveMongoOperations operations; - private boolean createIndexesForQueryMethods = false; + + @Deprecated private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; /** @@ -65,7 +66,10 @@ public void setReactiveMongoOperations(@Nullable ReactiveMongoOperations operati * Configures whether to automatically create indexes for the properties referenced in a query method. * * @param createIndexesForQueryMethods the createIndexesForQueryMethods to set + * @deprecated since 2.2. Use {@link org.springframework.data.mongodb.core.index.IndexOperations} to define and create + * indexes. */ + @Deprecated public void setCreateIndexesForQueryMethods(boolean createIndexesForQueryMethods) { this.createIndexesForQueryMethods = createIndexesForQueryMethods; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java index de4d6d52de..ff8d495dba 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java @@ -30,25 +30,26 @@ import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.dao.DataAccessException; +import org.springframework.data.mongodb.MongoCollectionUtils; import org.springframework.data.mongodb.MongoDbFactory; -import org.springframework.data.mongodb.core.CollectionCallback; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.convert.MappingMongoConverter; +import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.mongodb.MongoException; -import com.mongodb.client.MongoCollection; - /** * Integration tests for index handling. * * @author Oliver Gierke * @author Christoph Strobl * @author Jordi Llach + * @author Mark Paluch */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:infrastructure.xml") @@ -72,6 +73,21 @@ public void createsIndexWithFieldName() { assertThat(hasIndex("_firstname", IndexedPerson.class), is(true)); } + @Test // DATAMONGO-237 + @DirtiesContext + public void shouldNotCreateIndexOnIndexingDisabled() { + + MongoMappingContext context = new MongoMappingContext(); + context.setAutoIndexCreation(false); + + MongoTemplate template = new MongoTemplate(mongoDbFactory, + new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context)); + + template.getConverter().getMappingContext().getPersistentEntity(IndexedPerson.class); + + assertThat(hasIndex("_firstname", MongoCollectionUtils.getPreferredCollectionName(IndexedPerson.class)), is(false)); + } + @Test // DATAMONGO-1163 @DirtiesContext public void createsIndexFromMetaAnnotation() { @@ -101,22 +117,30 @@ class IndexedPerson { * @param entityType * @return */ - private boolean hasIndex(final String indexName, Class entityType) { + private boolean hasIndex(String indexName, Class entityType) { + return hasIndex(indexName, operations.getCollectionName(entityType)); + } + + /** + * Returns whether an index with the given name exists for the given collection. + * + * @param indexName + * @param collectionName + * @return + */ + private boolean hasIndex(String indexName, String collectionName) { - return operations.execute(entityType, new CollectionCallback() { - public Boolean doInCollection(MongoCollection collection) - throws MongoException, DataAccessException { + return operations.execute(collectionName, collection -> { - List indexes = new ArrayList(); - collection.listIndexes(org.bson.Document.class).into(indexes); + List indexes = new ArrayList<>(); + collection.listIndexes(org.bson.Document.class).into(indexes); - for (org.bson.Document indexInfo : indexes) { - if (indexName.equals(indexInfo.get("name"))) { - return true; - } + for (org.bson.Document indexInfo : indexes) { + if (indexName.equals(indexInfo.get("name"))) { + return true; } - return false; } + return false; }); } } From fe539a72a73a3faeb248f78ba3a6c86d75606f8f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 16 Jan 2019 14:52:52 +0100 Subject: [PATCH 4/5] DATAMONGO-2188 - Expose IndexResolver. We now provide IndexResolver to resolve and derive index definitions from Mongo entities. MongoMappingContext mappingContext = new MongoMappingContext(); IndexResolver indexResolver = IndexResolver.create(mappingContext); Iterable definitions = indexResolver.resolveIndexFor(MyEntity.class); --- .../mongodb/core/index/IndexResolver.java | 31 ++++++++++++++++++- .../MongoPersistentEntityIndexCreator.java | 2 +- ...tiveMongoPersistentEntityIndexCreator.java | 2 +- ...ersistentEntityIndexResolverUnitTests.java | 13 +++++++- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java index f2765c2465..5bdc8028d7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java @@ -16,16 +16,33 @@ package org.springframework.data.mongodb.core.index; import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver.IndexDefinitionHolder; +import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.util.Assert; /** * {@link IndexResolver} finds those {@link IndexDefinition}s to be created for a given class. * * @author Christoph Strobl * @author Thomas Darimont + * @author Mark Paluch * @since 1.5 */ -interface IndexResolver { +public interface IndexResolver { + + /** + * Creates a new {@link IndexResolver} given {@link MongoMappingContext}. + * + * @param mappingContext must not be {@literal null}. + * @return the new {@link IndexResolver}. + */ + static IndexResolver create(MongoMappingContext mappingContext) { + + Assert.notNull(mappingContext, "MongoMappingContext must not be null!"); + + return new MongoPersistentEntityIndexResolver(mappingContext); + } /** * Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s @@ -36,4 +53,16 @@ interface IndexResolver { */ Iterable resolveIndexFor(TypeInformation typeInformation); + /** + * Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s + * are created for properties and types with {@link Indexed}, {@link CompoundIndexes} or {@link GeoSpatialIndexed}. + * + * @param entityType + * @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type. + * @see 2.2 + */ + default Iterable resolveIndexFor(Class entityType) { + return resolveIndexFor(ClassTypeInformation.from(entityType)); + } + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index 80d5966daf..eeef8af4b3 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -69,7 +69,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener definitions = indexResolver.resolveIndexFor(IndexOnLevelOne.class); + + assertThat(definitions.iterator().hasNext(), is(true)); + } + + @Test // DATAMONGO-899 + public void deeplyNestedIndexPathIsResolvedCorrectly() { List indexDefinitions = prepareMappingContextAndResolveIndexForType(IndexOnLevelTwo.class); From f4d5d5f2de2dca2d92b0b0c7aef4467621929fd0 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 22 Jan 2019 11:56:55 +0100 Subject: [PATCH 5/5] DATAMONGO-2188 - Polishing. Undo deprecation and transition to configuration option allowing to disable the index creation. Index creation will remain in the codebase as it is used in a lot of places to configure required geo index structures in MongoDB without which query execution would fail. --- .../config/MongoConfigurationSupport.java | 13 +++ .../mongodb/core/ReactiveMongoTemplate.java | 1 + .../mongodb/core/index/IndexResolver.java | 5 +- .../mongodb/core/index/JustOnceLogger.java | 84 +++++++++++++++++++ .../index/MongoMappingEventPublisher.java | 2 - .../MongoPersistentEntityIndexCreator.java | 11 ++- ...tiveMongoPersistentEntityIndexCreator.java | 9 +- .../core/mapping/MongoMappingContext.java | 12 +-- .../IndexEnsuringQueryCreationListener.java | 3 - .../support/MongoRepositoryFactoryBean.java | 5 +- .../ReactiveMongoRepositoryFactoryBean.java | 6 +- .../core/index/IndexingIntegrationTests.java | 2 +- ...ersistentEntityIndexResolverUnitTests.java | 2 +- src/main/asciidoc/reference/mapping.adoc | 23 ++++- 14 files changed, 151 insertions(+), 27 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/JustOnceLogger.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java index d6562f75fd..bb8406e384 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java @@ -87,6 +87,7 @@ public MongoMappingContext mongoMappingContext() throws ClassNotFoundException { mappingContext.setInitialEntitySet(getInitialEntitySet()); mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder()); mappingContext.setFieldNamingStrategy(fieldNamingStrategy()); + mappingContext.setAutoIndexCreation(autoIndexCreation()); return mappingContext; } @@ -190,4 +191,16 @@ protected FieldNamingStrategy fieldNamingStrategy() { return abbreviateFieldNames() ? new CamelCaseAbbreviatingFieldNamingStrategy() : PropertyNameFieldNamingStrategy.INSTANCE; } + + /** + * Configure whether to automatically create indices for domain types by deriving the + * {@link org.springframework.data.mongodb.core.index.IndexDefinition} from the entity or not. + * + * @return {@literal true} by default.
+ * INFO: As of 3.x the default will be set to {@literal false}. + * @since 2.2 + */ + protected boolean autoIndexCreation() { + return true; + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 34901303fb..640f449cd6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -3185,6 +3185,7 @@ public void onApplicationEvent(MappingContextEvent event) { // Double check type as Spring infrastructure does not consider nested generics if (entity instanceof MongoPersistentEntity) { + onCheckForIndexes((MongoPersistentEntity) entity, subscriptionExceptionHandler); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java index 5bdc8028d7..0bc0bedc92 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexResolver.java @@ -15,7 +15,6 @@ */ package org.springframework.data.mongodb.core.index; -import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver.IndexDefinitionHolder; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -51,7 +50,7 @@ static IndexResolver create(MongoMappingContext mappingContext) { * @param typeInformation * @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type. */ - Iterable resolveIndexFor(TypeInformation typeInformation); + Iterable resolveIndexFor(TypeInformation typeInformation); /** * Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s @@ -61,7 +60,7 @@ static IndexResolver create(MongoMappingContext mappingContext) { * @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type. * @see 2.2 */ - default Iterable resolveIndexFor(Class entityType) { + default Iterable resolveIndexFor(Class entityType) { return resolveIndexFor(ClassTypeInformation.from(entityType)); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/JustOnceLogger.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/JustOnceLogger.java new file mode 100644 index 0000000000..8b172b007a --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/JustOnceLogger.java @@ -0,0 +1,84 @@ +/* + * Copyright 2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.mongodb.core.index; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Christoph Strobl + * @since 2.2 + */ +class JustOnceLogger { + + private static final Map> KNOWN_LOGS = new ConcurrentHashMap<>(); + private static final String AUTO_INDEX_CREATION_CONFIG_CHANGE; + + static { + AUTO_INDEX_CREATION_CONFIG_CHANGE = "Automatic index creation will be disabled by default as of Spring Data MongoDB 3.x." + + System.lineSeparator() + + "\tPlease use 'MongoMappingContext#setAutoIndexCreation(boolean)' or override 'MongoConfigurationSupport#autoIndexCreation()' to be explicit." + + System.lineSeparator() + + "\tHowever, we recommend setting up indices manually in an application ready block. You may use index derivation there as well." + + System.lineSeparator() + System.lineSeparator() // + + "\t> -----------------------------------------------------------------------------------------" + + System.lineSeparator() // + + "\t> @EventListener(ApplicationReadyEvent.class)" + System.lineSeparator() // + + "\t> public void initIndicesAfterStartup() {" + System.lineSeparator() // + + "\t>" + System.lineSeparator() // + + "\t> IndexOperations indexOps = mongoTemplate.indexOps(DomainType.class);" + System.lineSeparator()// + + "\t>" + System.lineSeparator() // + + "\t> IndexResolver resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);" + + System.lineSeparator() // + + "\t> resolver.resolveIndexFor(DomainType.class).forEach(indexOps::ensureIndex);" + System.lineSeparator() // + + "\t> }" + System.lineSeparator() // + + "\t> -----------------------------------------------------------------------------------------" + + System.lineSeparator(); + } + + static void logWarnIndexCreationConfigurationChange(String loggerName) { + warnOnce(loggerName, AUTO_INDEX_CREATION_CONFIG_CHANGE); + } + + static void warnOnce(String loggerName, String message) { + + Logger logger = LoggerFactory.getLogger(loggerName); + if (!logger.isWarnEnabled()) { + return; + } + + if (!KNOWN_LOGS.containsKey(loggerName)) { + + KNOWN_LOGS.put(loggerName, new ConcurrentSkipListSet<>(Collections.singleton(message))); + logger.warn(message); + } else { + + Set messages = KNOWN_LOGS.get(loggerName); + if (messages.contains(message)) { + return; + } + + messages.add(message); + logger.warn(message); + } + } +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java index 6bba8eb8f2..0c8fdb415f 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoMappingEventPublisher.java @@ -36,9 +36,7 @@ * @author Jon Brisbin * @author Oliver Gierke * @author Mark Paluch - * @deprecated since 2.2. Use {@link IndexOperations} to define and create indexes. */ -@Deprecated public class MongoMappingEventPublisher implements ApplicationEventPublisher { private final ApplicationListener> indexCreator; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java index eeef8af4b3..223a625b2e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexCreator.java @@ -110,6 +110,7 @@ public void onApplicationEvent(MappingContextEvent event) { // Double check type as Spring infrastructure does not consider nested generics if (entity instanceof MongoPersistentEntity) { + checkForIndexes((MongoPersistentEntity) entity); } } @@ -133,8 +134,16 @@ private void checkForIndexes(final MongoPersistentEntity entity) { private void checkForAndCreateIndexes(MongoPersistentEntity entity) { if (entity.isAnnotationPresent(Document.class)) { - for (IndexDefinitionHolder indexToCreate : indexResolver.resolveIndexFor(entity.getTypeInformation())) { + for (IndexDefinition indexDefinition : indexResolver.resolveIndexFor(entity.getTypeInformation())) { + + JustOnceLogger.logWarnIndexCreationConfigurationChange(this.getClass().getName()); + + IndexDefinitionHolder indexToCreate = indexDefinition instanceof IndexDefinitionHolder + ? (IndexDefinitionHolder) indexDefinition + : new IndexDefinitionHolder("", indexDefinition, entity.getCollection()); + createIndex(indexToCreate); + } } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/ReactiveMongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/ReactiveMongoPersistentEntityIndexCreator.java index 00f19bbd14..c8561fd9c2 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/ReactiveMongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/ReactiveMongoPersistentEntityIndexCreator.java @@ -125,7 +125,12 @@ private Mono checkForAndCreateIndexes(MongoPersistentEntity entity) { List> publishers = new ArrayList<>(); if (entity.isAnnotationPresent(Document.class)) { - for (IndexDefinitionHolder indexToCreate : indexResolver.resolveIndexFor(entity.getTypeInformation())) { + for (IndexDefinition indexDefinition : indexResolver.resolveIndexFor(entity.getTypeInformation())) { + + IndexDefinitionHolder indexToCreate = indexDefinition instanceof IndexDefinitionHolder + ? (IndexDefinitionHolder) indexDefinition + : new IndexDefinitionHolder("", indexDefinition, entity.getCollection()); + publishers.add(createIndex(indexToCreate)); } } @@ -135,6 +140,8 @@ private Mono checkForAndCreateIndexes(MongoPersistentEntity entity) { Mono createIndex(IndexDefinitionHolder indexDefinition) { + JustOnceLogger.logWarnIndexCreationConfigurationChange(this.getClass().getName()); + return operationsProvider.indexOps(indexDefinition.getCollection()).ensureIndex(indexDefinition) // .onErrorResume(ReactiveMongoPersistentEntityIndexCreator::isDataIntegrityViolation, e -> translateException(e, indexDefinition)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java index b69aada3fc..0c82b70a62 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java @@ -104,8 +104,9 @@ public void setApplicationContext(ApplicationContext applicationContext) throws } /** - * Returns whether auto-index creation is enabled or disabled. Please note that auto-index creation is deprecated. - * Index creation should happen at a well-defined time that is ideally controlled by the application itself. + * Returns whether auto-index creation is enabled or disabled.
+ * NOTE:Index creation should happen at a well-defined time that is ideally controlled by the + * application itself. * * @return {@literal true} when auto-index creation is enabled; {@literal false} otherwise. * @since 2.2 @@ -116,10 +117,11 @@ public boolean isAutoIndexCreation() { } /** - * Enables/disables auto-index creation. Please note that auto-index creation is deprecated. Index creation should - * happen at a well-defined time that is ideally controlled by the application its + * Enables/disables auto-index creation.
+ * NOTE:Index creation should happen at a well-defined time that is ideally controlled by the + * application itself. * - * @param autoCreateIndexes {@literal true} to enable auto-index creation. Enabled by default. + * @param autoCreateIndexes set to {@literal false} to disable auto-index creation. * @since 2.2 * @see org.springframework.data.mongodb.core.index.Indexed */ diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java index 0bf973acbe..eb0a38b199 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java @@ -42,10 +42,7 @@ * @author Oliver Gierke * @author Mark Paluch * @author Christoph Strobl - * @deprecated since 2.2. Use {@link org.springframework.data.mongodb.core.index.IndexOperations} to define and create - * indexes. */ -@Deprecated class IndexEnsuringQueryCreationListener implements QueryCreationListener { private static final Set GEOSPATIAL_TYPES = new HashSet(Arrays.asList(Type.NEAR, Type.WITHIN)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java index 8795eb976d..998500be82 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java @@ -35,7 +35,7 @@ public class MongoRepositoryFactoryBean, S, ID exten extends RepositoryFactoryBeanSupport { private @Nullable MongoOperations operations; - @Deprecated private boolean createIndexesForQueryMethods = false; + private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; /** @@ -60,10 +60,7 @@ public void setMongoOperations(MongoOperations operations) { * Configures whether to automatically create indexes for the properties referenced in a query method. * * @param createIndexesForQueryMethods the createIndexesForQueryMethods to set - * @deprecated since 2.2. Use {@link org.springframework.data.mongodb.core.index.IndexOperations} to define and create - * indexes. */ - @Deprecated public void setCreateIndexesForQueryMethods(boolean createIndexesForQueryMethods) { this.createIndexesForQueryMethods = createIndexesForQueryMethods; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java index c44828c0c1..277b7d6a74 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java @@ -40,8 +40,7 @@ public class ReactiveMongoRepositoryFactoryBean, S, extends RepositoryFactoryBeanSupport { private @Nullable ReactiveMongoOperations operations; - - @Deprecated private boolean createIndexesForQueryMethods = false; + private boolean createIndexesForQueryMethods = false; private boolean mappingContextConfigured = false; /** @@ -66,10 +65,7 @@ public void setReactiveMongoOperations(@Nullable ReactiveMongoOperations operati * Configures whether to automatically create indexes for the properties referenced in a query method. * * @param createIndexesForQueryMethods the createIndexesForQueryMethods to set - * @deprecated since 2.2. Use {@link org.springframework.data.mongodb.core.index.IndexOperations} to define and create - * indexes. */ - @Deprecated public void setCreateIndexesForQueryMethods(boolean createIndexesForQueryMethods) { this.createIndexesForQueryMethods = createIndexesForQueryMethods; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java index ff8d495dba..32b7acd6b5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java @@ -73,7 +73,7 @@ public void createsIndexWithFieldName() { assertThat(hasIndex("_firstname", IndexedPerson.class), is(true)); } - @Test // DATAMONGO-237 + @Test // DATAMONGO-2188 @DirtiesContext public void shouldNotCreateIndexOnIndexingDisabled() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java index 6014050bcf..4c0e4576eb 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/MongoPersistentEntityIndexResolverUnitTests.java @@ -92,7 +92,7 @@ public void shouldResolveIndexViaClass() { MongoMappingContext mappingContext = new MongoMappingContext(); IndexResolver indexResolver = IndexResolver.create(mappingContext); - Iterable definitions = indexResolver.resolveIndexFor(IndexOnLevelOne.class); + Iterable definitions = indexResolver.resolveIndexFor(IndexOnLevelOne.class); assertThat(definitions.iterator().hasNext(), is(true)); } diff --git a/src/main/asciidoc/reference/mapping.adoc b/src/main/asciidoc/reference/mapping.adoc index c495b2ef25..05e2e63cf7 100644 --- a/src/main/asciidoc/reference/mapping.adoc +++ b/src/main/asciidoc/reference/mapping.adoc @@ -377,8 +377,29 @@ public class Person { ==== IMPORTANT: The `@Id` annotation tells the mapper which property you want to use for the MongoDB `_id` property, and the `@Indexed` annotation tells the mapping framework to call `createIndex(…)` on that property of your document, making searches faster. +Automatic index creation is only done for types annotated with `@Document`. -IMPORTANT: Automatic index creation is deprecated since version 2.2 because controlling the actual time of index creation is rather difficult. Index creation can be part of the application startup, happen during runtime or an out of band process. Therefore, Spring Data MongoDB backs off entirely and recommends index creation to happen either out of band or as part of the application startup using `IndexOperations`. Automatic index creation is still available and is is only done for types annotated with `@Document`. +[NOTE] +==== +To turn automatic index creation _OFF_ please override `autoIndexCreation()` in your configuration. +[source,java] +---- +@Configuration +public class Config extends AbstractMongoClientConfiguration { + + @Override + public boolean autoIndexCreation() { + return false; + } + + // ... +} +---- +==== + +IMPORTANT: Automatic index creation will be turned _OFF_ by default with the release of 3.x. +We recommend index creation to happen either out of band or as part of the application startup using +`IndexOperations`. We'll once add a `WARN` to your log when we encounter automatic index creation. [[mapping-usage-annotations]] === Mapping Annotation Overview