Skip to content

Commit a21c57f

Browse files
Fix index creation
1 parent d946954 commit a21c57f

File tree

8 files changed

+54
-10
lines changed

8 files changed

+54
-10
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/DefaultIndexOperationsProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class DefaultIndexOperationsProvider implements IndexOperationsProvider {
4747
* @see org.springframework.data.mongodb.core.index.IndexOperationsProvider#reactiveIndexOps(java.lang.String)
4848
*/
4949
@Override
50-
public IndexOperations indexOps(String collectionName) {
51-
return new DefaultIndexOperations(mongoDbFactory, collectionName, mapper);
50+
public IndexOperations indexOps(String collectionName, Class<?> type) {
51+
return new DefaultIndexOperations(mongoDbFactory, collectionName, mapper, type);
5252
}
5353
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,20 +715,26 @@ public void dropCollection(String collectionName) {
715715
});
716716
}
717717

718+
719+
@Override
720+
public IndexOperations indexOps(String collectionName) {
721+
return indexOps(collectionName, null);
722+
}
723+
718724
/*
719725
* (non-Javadoc)
720726
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.String)
721727
*/
722-
public IndexOperations indexOps(String collectionName) {
723-
return new DefaultIndexOperations(this, collectionName, null);
728+
public IndexOperations indexOps(String collectionName, @Nullable Class<?> type) {
729+
return new DefaultIndexOperations(this, collectionName, type);
724730
}
725731

726732
/*
727733
* (non-Javadoc)
728734
* @see org.springframework.data.mongodb.core.ExecutableInsertOperation#indexOps(java.lang.Class)
729735
*/
730736
public IndexOperations indexOps(Class<?> entityClass) {
731-
return new DefaultIndexOperations(this, getCollectionName(entityClass), entityClass);
737+
return indexOps(getCollectionName(entityClass), entityClass);
732738
}
733739

734740
/*

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/index/IndexOperationsProvider.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.data.mongodb.core.index;
1717

18+
import org.springframework.lang.Nullable;
19+
1820
/**
1921
* Provider interface to obtain {@link IndexOperations} by MongoDB collection name.
2022
*
@@ -25,11 +27,23 @@
2527
@FunctionalInterface
2628
public interface IndexOperationsProvider {
2729

30+
/**
31+
* Returns the operations that can be performed on indexes
32+
*
33+
* @param collectionName name of the MongoDB collection, must not be {@literal null}.
34+
* @param type the type used for field mapping. Can be {@literal null}.
35+
* @return index operations on the named collection
36+
* @since 2.5
37+
*/
38+
IndexOperations indexOps(String collectionName, @Nullable Class<?> type);
39+
2840
/**
2941
* Returns the operations that can be performed on indexes
3042
*
3143
* @param collectionName name of the MongoDB collection, must not be {@literal null}.
3244
* @return index operations on the named collection
3345
*/
34-
IndexOperations indexOps(String collectionName);
46+
default IndexOperations indexOps(String collectionName) {
47+
return indexOps(collectionName, null);
48+
}
3549
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListener.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515
*/
1616
package org.springframework.data.mongodb.repository.support;
1717

18+
import java.lang.reflect.Field;
1819
import java.util.Arrays;
1920
import java.util.HashSet;
2021
import java.util.Set;
2122

2223
import org.slf4j.Logger;
2324
import org.slf4j.LoggerFactory;
25+
import org.springframework.core.annotation.AnnotatedElementUtils;
26+
import org.springframework.data.annotation.Embedded;
2427
import org.springframework.data.domain.Sort;
2528
import org.springframework.data.domain.Sort.Direction;
2629
import org.springframework.data.domain.Sort.Order;
@@ -36,8 +39,10 @@
3639
import org.springframework.data.repository.query.parser.Part.Type;
3740
import org.springframework.data.repository.query.parser.PartTree;
3841
import org.springframework.util.Assert;
42+
import org.springframework.util.ReflectionUtils;
3943

4044
import com.mongodb.MongoException;
45+
import org.springframework.util.StringUtils;
4146

4247
/**
4348
* {@link QueryCreationListener} inspecting {@link PartTreeMongoQuery}s and creating an index for the properties it
@@ -82,9 +87,14 @@ public void onCreation(PartTreeMongoQuery query) {
8287
Sort sort = tree.getSort();
8388

8489
for (Part part : tree.getParts()) {
90+
8591
if (GEOSPATIAL_TYPES.contains(part.getType())) {
8692
return;
8793
}
94+
if(isIndexOnEmbeddedType(part)) {
95+
return;
96+
}
97+
8898
String property = part.getProperty().toDotPath();
8999
Direction order = toDirection(sort, property);
90100
index.on(property, order);
@@ -107,7 +117,7 @@ public void onCreation(PartTreeMongoQuery query) {
107117

108118
MongoEntityMetadata<?> metadata = query.getQueryMethod().getEntityInformation();
109119
try {
110-
indexOperationsProvider.indexOps(metadata.getCollectionName()).ensureIndex(index);
120+
indexOperationsProvider.indexOps(metadata.getCollectionName(), metadata.getJavaType()).ensureIndex(index);
111121
} catch (UncategorizedMongoDbException e) {
112122

113123
if (e.getCause() instanceof MongoException) {
@@ -129,6 +139,19 @@ public void onCreation(PartTreeMongoQuery query) {
129139
LOG.debug(String.format("Created %s!", index));
130140
}
131141

142+
public boolean isIndexOnEmbeddedType(Part part) {
143+
144+
// TODO we could do it for nested fields in the
145+
Field field = ReflectionUtils.findField(part.getProperty().getOwningType().getType(),
146+
part.getProperty().getSegment());
147+
148+
if (field == null) {
149+
return false;
150+
}
151+
152+
return AnnotatedElementUtils.hasAnnotation(field, Embedded.class);
153+
}
154+
132155
private static Direction toDirection(Sort sort, String property) {
133156

134157
if (sort.isUnsorted()) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/MongoRepositoryFactoryBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ protected RepositoryFactorySupport createRepositoryFactory() {
9090

9191
if (createIndexesForQueryMethods) {
9292
factory.addQueryCreationListener(
93-
new IndexEnsuringQueryCreationListener(collectionName -> operations.indexOps(collectionName)));
93+
new IndexEnsuringQueryCreationListener((collectionName, javaType) -> operations.indexOps(javaType)));
9494
}
9595

9696
return factory;

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/ReactiveMongoRepositoryFactoryBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ protected RepositoryFactorySupport createRepositoryFactory() {
9797

9898
if (createIndexesForQueryMethods) {
9999
factory.addQueryCreationListener(new IndexEnsuringQueryCreationListener(
100-
collectionName -> IndexOperationsAdapter.blocking(operations.indexOps(collectionName))));
100+
(collectionName, javaType) -> IndexOperationsAdapter.blocking(operations.indexOps(javaType))));
101101
}
102102

103103
return factory;

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/RepositoryIndexCreationIntegrationTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public void testname() {
7878

7979
assertHasIndexForField(indexInfo, "lastname");
8080
assertHasIndexForField(indexInfo, "firstname");
81+
assertHasIndexForField(indexInfo, "add");
8182
}
8283

8384
private static void assertHasIndexForField(List<IndexInfo> indexInfo, String... fields) {

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/IndexEnsuringQueryCreationListenerUnitTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void setUp() {
6666

6767
partTreeQuery = mock(PartTreeMongoQuery.class, Answers.RETURNS_MOCKS);
6868
when(partTreeQuery.getTree()).thenReturn(partTree);
69-
when(provider.indexOps(anyString())).thenReturn(indexOperations);
69+
when(provider.indexOps(anyString(), any())).thenReturn(indexOperations);
7070
when(queryMethod.getEntityInformation()).thenReturn(entityInformation);
7171
when(entityInformation.getCollectionName()).thenReturn("persons");
7272
}

0 commit comments

Comments
 (0)