Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
package org.springframework.data.mongodb.core.index;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.mongodb.MongoException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
Expand Down Expand Up @@ -50,12 +51,13 @@
* @author Laurent Canet
* @author Christoph Strobl
* @author Mark Paluch
* @author Nick Balkissoon
*/
public class MongoPersistentEntityIndexCreator implements ApplicationListener<MappingContextEvent<?, ?>> {

private static final Logger LOGGER = LoggerFactory.getLogger(MongoPersistentEntityIndexCreator.class);

private final Map<Class<?>, Boolean> classesSeen = new ConcurrentHashMap<Class<?>, Boolean>();
private final Table<Class, String, Boolean> collectionsSeen = HashBasedTable.create();
private final IndexOperationsProvider indexOperationsProvider;
private final MongoMappingContext mappingContext;
private final IndexResolver indexResolver;
Expand Down Expand Up @@ -119,12 +121,15 @@ private void checkForIndexes(final MongoPersistentEntity<?> entity) {

Class<?> type = entity.getType();

if (!classesSeen.containsKey(type)) {
String collection = entity.getCollection();

if (!collectionsSeen.contains(type, collection)) {

this.classesSeen.put(type, Boolean.TRUE);
this.collectionsSeen.put(type, collection, Boolean.TRUE);

if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Analyzing class " + type + " for index information.");
LOGGER.debug("Analyzing class " + type
+ " for index information in collection " + collection);
}

checkForAndCreateIndexes(entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;

import java.util.Collections;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.TimeUnit;

import org.junit.Before;
Expand Down Expand Up @@ -54,6 +55,7 @@
* @author Christoph Strobl
* @author Thomas Darimont
* @author Mark Paluch
* @author Nick Balkissoon
*/
@RunWith(MockitoJUnitRunner.class)
public class MongoPersistentEntityIndexCreatorUnitTests {
Expand Down Expand Up @@ -218,12 +220,62 @@ public void createIndexShouldNotConvertUnknownExceptionTypes() {
new MongoPersistentEntityIndexCreator(mappingContext, mongoTemplate);
}

private static MongoMappingContext prepareMappingContext(Class<?> type) {
@Test // DATAMONGO-719
public void createIndexShouldCreateIndexesForSamePersistentEntityButDifferentCollectionName() {

String collection1 = "collection1";
DynamicCollectionRouter.collectionName = collection1;
MongoMappingContext mappingContext = prepareMappingContext(DynamicCollectionDocument.class);

MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mappingContext, mongoTemplate);

MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty> event = new MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>(mappingContext, mappingContext.getRequiredPersistentEntity(DynamicCollectionDocument.class));

String collection2 = "collection2";
DynamicCollectionRouter.collectionName = collection2;

indexCreator.onApplicationEvent(event);
indexCreator.onApplicationEvent(event);

ArgumentCaptor<String> collectionNameCapturer = ArgumentCaptor.forClass(String.class);
verify(db, times(2)).getCollection(collectionNameCapturer.capture(), any());
assertThat(collection1).isEqualTo(collectionNameCapturer.getAllValues().get(0));
assertThat(collection2).isEqualTo(collectionNameCapturer.getAllValues().get(1));
}

@Test // DATAMONGO-719
public void createIndexShouldCreateIndexesForDifferentPersistentEntitySameCollectionName() {

String collection1 = "collection1";
DynamicCollectionRouter.collectionName = collection1;
MongoMappingContext mappingContext = prepareMappingContext(DynamicCollectionDocument.class, AnotherDynamicCollectionDocument.class);

MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mappingContext, mongoTemplate);

MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty> event = new MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>(mappingContext, mappingContext.getRequiredPersistentEntity(DynamicCollectionDocument.class));
MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty> otherEvent = new MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>(mappingContext, mappingContext.getRequiredPersistentEntity(AnotherDynamicCollectionDocument.class));

String collection2 = "collection2";
DynamicCollectionRouter.collectionName = collection2;

indexCreator.onApplicationEvent(event);
indexCreator.onApplicationEvent(otherEvent);
indexCreator.onApplicationEvent(event);
indexCreator.onApplicationEvent(otherEvent);

ArgumentCaptor<String> collectionNameCapturer = ArgumentCaptor.forClass(String.class);
verify(db, times(4)).getCollection(collectionNameCapturer.capture(), any());
assertThat(collection1).isEqualTo(collectionNameCapturer.getAllValues().get(0));
assertThat(collection1).isEqualTo(collectionNameCapturer.getAllValues().get(1));
assertThat(collection2).isEqualTo(collectionNameCapturer.getAllValues().get(2));
assertThat(collection2).isEqualTo(collectionNameCapturer.getAllValues().get(3));
}

private static MongoMappingContext prepareMappingContext(Class<?>... types) {

MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(Collections.singleton(type));
mappingContext.setInitialEntitySet(new HashSet<>(Arrays.asList(types)));
mappingContext.initialize();

return mappingContext;
}

Expand Down Expand Up @@ -286,4 +338,31 @@ class EntityWithGeneratedIndexName {

@Indexed(useGeneratedName = true, name = "ignored") String lastname;
}

static class DynamicCollectionRouter {
static String collectionName;

public static String determineCollection() {
return collectionName;
}
}

private static final String dynamicCollectionSpel = "#{ T(org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreatorUnitTests.DynamicCollectionRouter).determineCollection()}";

@Document(collection = dynamicCollectionSpel)
static class DynamicCollectionDocument {

@Indexed
String field;

}

@Document(collection = dynamicCollectionSpel)
static class AnotherDynamicCollectionDocument {

@Indexed
String anotherField;

}

}