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 d6562f75f..bb8406e38 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 abstract class MongoConfigurationSupport {
mappingContext.setInitialEntitySet(getInitialEntitySet());
mappingContext.setSimpleTypeHolder(customConversions().getSimpleTypeHolder());
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
+ mappingContext.setAutoIndexCreation(autoIndexCreation());
return mappingContext;
}
@@ -190,4 +191,16 @@ public abstract class MongoConfigurationSupport {
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 34901303f..640f449cd 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 class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
// 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 5bdc8028d..3e7001b0c 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;
@@ -36,6 +35,7 @@ public interface IndexResolver {
*
* @param mappingContext must not be {@literal null}.
* @return the new {@link IndexResolver}.
+ * @since 2.2
*/
static IndexResolver create(MongoMappingContext mappingContext) {
@@ -51,7 +51,7 @@ public interface IndexResolver {
* @param typeInformation
* @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type.
*/
- Iterable extends IndexDefinitionHolder> resolveIndexFor(TypeInformation> typeInformation);
+ Iterable extends IndexDefinition> resolveIndexFor(TypeInformation> typeInformation);
/**
* Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s
@@ -61,7 +61,7 @@ public interface IndexResolver {
* @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type.
* @see 2.2
*/
- default Iterable extends IndexDefinitionHolder> resolveIndexFor(Class> entityType) {
+ default Iterable extends IndexDefinition> 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 000000000..8b172b007
--- /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 6bba8eb8f..0c8fdb415 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 @@ import org.springframework.util.Assert;
* @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 eeef8af4b..223a625b2 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 class MongoPersistentEntityIndexCreator implements ApplicationListener) entity);
}
}
@@ -133,8 +134,16 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener 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 00f19bbd1..c8561fd9c 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 @@ public class ReactiveMongoPersistentEntityIndexCreator {
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 @@ public class ReactiveMongoPersistentEntityIndexCreator {
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 b69aada3f..0c82b70a6 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 class MongoMappingContext extends AbstractMappingContext
+ * 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 class MongoMappingContext extends AbstractMappingContext
+ * 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 0bf973acb..eb0a38b19 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 @@ import org.springframework.util.Assert;
* @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 8795eb976..998500be8 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 class MongoRepositoryFactoryBean, S, ID exten
* 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 c44828c0c..277b7d6a7 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 class ReactiveMongoRepositoryFactoryBean, S,
* 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 ff8d495db..32b7acd6b 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 class IndexingIntegrationTests {
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 6014050bc..e5be79d43 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
@@ -87,12 +87,12 @@ public class MongoPersistentEntityIndexResolverUnitTests {
assertIndexPathAndCollection("zero.indexedProperty", "One", indexDefinitions.get(0));
}
- @Test // DATAMONGO-899
+ @Test // DATAMONGO-899, DATAMONGO-2188
public void shouldResolveIndexViaClass() {
MongoMappingContext mappingContext = new MongoMappingContext();
IndexResolver indexResolver = IndexResolver.create(mappingContext);
- Iterable extends IndexDefinitionHolder> definitions = indexResolver.resolveIndexFor(IndexOnLevelOne.class);
+ Iterable extends IndexDefinition> 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 c495b2ef2..2f9710499 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`.
[[mapping-usage-annotations]]
=== Mapping Annotation Overview