From ad287efb4eafff04a15306997cd88aea0f5ea555 Mon Sep 17 00:00:00 2001 From: "J. Brisbin" Date: Fri, 20 May 2011 11:36:17 -0500 Subject: [PATCH] DATADOC-143 - Made MongoMappingContext the default converter for the template, which also meant: Several changes to how objects are initialized inside the template: 1. In one is not specified, a MappingMongoConverter is created and set as the default. 2. A special ApplicationEventPublisher implementation is installed by default to handle creating indexes when the template isn't used inside a Spring application context. 3. If a Spring application context is available, it will be set as the template's application context and eventPublisher, with the index creator being registered as an event listener if one isn't already present. The tests had to be changed in a couple places to accurately reflect how mapping contexts and converters are now handled. --- .../data/document/mongodb/MongoTemplate.java | 130 ++++++++++-------- .../config/AbstractMongoConfiguration.java | 18 +-- .../config/MappingMongoConverterParser.java | 9 +- .../mongodb/config/MongoDbFactoryParser.java | 4 +- .../convert/MappingMongoConverter.java | 109 +++++++-------- .../MongoPersistentEntityIndexCreator.java | 9 +- .../event/MongoMappingEventPublisher.java | 6 +- .../document/mongodb/GeoSpatialAppConfig.java | 13 +- .../mongodb/MongoTemplateMappingTests.java | 12 -- .../document/mongodb/MongoTemplateTests.java | 24 ++-- .../mongodb/TestMongoConfiguration.java | 19 +-- .../convert/CustomConvertersUnitTests.java | 10 +- .../mongodb/mapping/GeoIndexedAppConfig.java | 14 +- .../mongodb/mapping/MappingTests.java | 2 +- .../src/test/resources/infrastructure.xml | 31 ++--- .../src/test/resources/mapping.xml | 20 ++- .../src/test/resources/template-mapping.xml | 7 +- 17 files changed, 208 insertions(+), 229 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java index 6c7b4eb92..c4bf66970 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/MongoTemplate.java @@ -40,8 +40,12 @@ import com.mongodb.util.JSON; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.convert.ConversionFailedException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; @@ -51,6 +55,7 @@ import org.springframework.data.document.mongodb.convert.MongoConverter; import org.springframework.data.document.mongodb.index.IndexDefinition; import org.springframework.data.document.mongodb.mapping.MongoMappingContext; import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity; +import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator; import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty; import org.springframework.data.document.mongodb.mapping.event.AfterConvertEvent; import org.springframework.data.document.mongodb.mapping.event.AfterLoadEvent; @@ -76,7 +81,7 @@ import org.springframework.util.Assert; * @author Mark Pollack * @author Oliver Gierke */ -public class MongoTemplate implements MongoOperations, ApplicationEventPublisherAware { +public class MongoTemplate implements MongoOperations, ApplicationContextAware { private static final Log LOGGER = LogFactory.getLog(MongoTemplate.class); @@ -99,13 +104,15 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher */ private boolean slaveOk = false; - private final MongoConverter mongoConverter; - private final MappingContext, MongoPersistentProperty> mappingContext; - private final MongoDbFactory mongoDbFactory; - private final MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator(); - private final QueryMapper mapper; + private MongoConverter mongoConverter; + private MappingContext, MongoPersistentProperty> mappingContext; + private MongoDbFactory mongoDbFactory; + private MongoExceptionTranslator exceptionTranslator = new MongoExceptionTranslator(); + private QueryMapper mapper; + private ApplicationContext applicationContext; private ApplicationEventPublisher eventPublisher; + private MongoPersistentEntityIndexCreator indexCreator; /** * Constructor used for a basic template configuration @@ -114,7 +121,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * @param databaseName */ public MongoTemplate(Mongo mongo, String databaseName) { - this(new MongoDbFactoryBean(mongo, databaseName)); + this(new MongoDbFactoryBean(mongo, databaseName), null, null, null); } /** @@ -126,7 +133,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * @param mongoConverter */ public MongoTemplate(Mongo mongo, String databaseName, MongoConverter mongoConverter) { - this(new MongoDbFactoryBean(mongo, databaseName), mongoConverter); + this(new MongoDbFactoryBean(mongo, databaseName), mongoConverter, null, null); } /** @@ -135,7 +142,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * @param mongoDbFactory */ public MongoTemplate(MongoDbFactory mongoDbFactory) { - this(mongoDbFactory, null); + this(mongoDbFactory, null, null, null); } /** @@ -162,37 +169,52 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher WriteConcern writeConcern, WriteResultChecking writeResultChecking) { Assert.notNull(mongoDbFactory); - + // Always need a MongoDbFactory for obtaining instances of DB this.mongoDbFactory = mongoDbFactory; - this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter() : mongoConverter; - this.writeConcern = writeConcern; - - if (this.mongoConverter instanceof MappingMongoConverter) { - initializeMappingMongoConverter((MappingMongoConverter) this.mongoConverter); + // Conversion of DBObject to POJO handled either custom or by default (MappingMongoConverter) + if (null == mongoConverter) { + this.mongoConverter = getDefaultMongoConverter(); + } else { + this.mongoConverter = mongoConverter; } - - this.mappingContext = this.mongoConverter.getMappingContext(); - this.mapper = new QueryMapper(this.mongoConverter); - + // We always have a mapping context in the converter, whether it's a simple one or not + mappingContext = this.mongoConverter.getMappingContext(); + // We create indexes based on mapping events + if (null != mappingContext && mappingContext instanceof MongoMappingContext) { + indexCreator = new MongoPersistentEntityIndexCreator((MongoMappingContext) mappingContext, mongoDbFactory); + eventPublisher = new MongoMappingEventPublisher(indexCreator); + if (mappingContext instanceof ApplicationEventPublisherAware) { + ((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher); + } + } + // WriteConcern + this.writeConcern = writeConcern; + // For converting ID names and values throughout Query objects + mapper = new QueryMapper(this.mongoConverter); + // Track WriteResults? if (writeResultChecking != null) { this.writeResultChecking = writeResultChecking; } - if (this.mappingContext instanceof MongoMappingContext) { - this.eventPublisher = new MongoMappingEventPublisher((MongoMappingContext) mappingContext, mongoDbFactory); - } - } private final MongoConverter getDefaultMongoConverter() { //ToDo: maybe add some additional configurations to this very basic one - MappingMongoConverter converter = new MappingMongoConverter(new MongoMappingContext()); + MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory, new MongoMappingContext()); converter.afterPropertiesSet(); return converter; } - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.eventPublisher = applicationEventPublisher; + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + String[] beans = applicationContext.getBeanNamesForType(MongoPersistentEntityIndexCreator.class); + if ((null == beans || beans.length == 0) && applicationContext instanceof ConfigurableApplicationContext) { + ((ConfigurableApplicationContext) applicationContext).addApplicationListener(indexCreator); + } + eventPublisher = applicationContext; + if (mappingContext instanceof ApplicationEventPublisherAware) { + ((ApplicationEventPublisherAware) mappingContext).setApplicationEventPublisher(eventPublisher); + } } /** @@ -213,9 +235,13 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher return this.mongoDbFactory; } + public MappingContext, MongoPersistentProperty> getMappingContext() { + return mappingContext; + } + /* (non-Javadoc) - * @see org.springframework.data.document.mongodb.MongoOperations#getDefaultCollectionName() - */ + * @see org.springframework.data.document.mongodb.MongoOperations#getDefaultCollectionName() + */ public String getCollectionName(Class clazz) { return this.determineCollectionName(clazz); } @@ -417,12 +443,12 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher public List find(String collectionName, Query query, Class targetClass, CursorPreparer preparer) { return doFind(collectionName, query.getQueryObject(), query.getFieldsObject(), targetClass, preparer); } - + public T findById(Object id, Class targetClass) { MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(targetClass); return findById(persistentEntity.getCollection(), id, targetClass); } - + public T findById(String collectionName, Object id, Class targetClass) { MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(targetClass); MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); @@ -455,15 +481,15 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher public void insert(String collectionName, Object objectToSave) { doInsert(collectionName, objectToSave, this.mongoConverter); } - + /** - * Prepare the collection before any processing is done using it. This allows a convenient way to apply + * Prepare the collection before any processing is done using it. This allows a convenient way to apply * settings like slaveOk() etc. Can be overridden in sub-classes. - * + * * @param collection */ protected void prepareCollection(DBCollection collection) { - if(this.slaveOk) { + if (this.slaveOk) { collection.slaveOk(); } } @@ -975,7 +1001,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher throw new MappingException(e.getMessage(), e); } } - + protected String getIdPropertyName(Object object) { MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(object.getClass()); MongoPersistentProperty idProperty = persistentEntity.getIdProperty(); @@ -1027,18 +1053,15 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher *
  • Execute the given {@link ConnectionCallback} for a {@link DBObject}.
  • *
  • Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.
  • *
      - * + * * @param - * @param collectionCallback - * the callback to retrieve the {@link DBObject} with - * @param objectCallback - * the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type - * @param collectionName - * the collection to be queried + * @param collectionCallback the callback to retrieve the {@link DBObject} with + * @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type + * @param collectionName the collection to be queried * @return */ private T executeFindOneInternal(CollectionCallback collectionCallback, DbObjectCallback objectCallback, - String collectionName) { + String collectionName) { try { T result = objectCallback.doWith(collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName))); @@ -1058,20 +1081,16 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher *
    1. Iterate over the {@link DBCursor} and applies the given {@link DbObjectCallback} to each of the * {@link DBObject}s collecting the actual result {@link List}.
    2. *
        - * + * * @param - * @param collectionCallback - * the callback to retrieve the {@link DBCursor} with - * @param preparer - * the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it - * @param objectCallback - * the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type - * @param collectionName - * the collection to be queried + * @param collectionCallback the callback to retrieve the {@link DBCursor} with + * @param preparer the {@link CursorPreparer} to potentially modify the {@link DBCursor} before ireating over it + * @param objectCallback the {@link DbObjectCallback} to transform {@link DBObject}s into the actual domain type + * @param collectionName the collection to be queried * @return */ private List executeFindMultiInternal(CollectionCallback collectionCallback, CursorPreparer preparer, - DbObjectCallback objectCallback, String collectionName) { + DbObjectCallback objectCallback, String collectionName) { try { DBCursor cursor = collectionCallback.doInCollection(getAndPrepareCollection(getDb(), collectionName)); @@ -1179,11 +1198,6 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher return resolved == null ? ex : resolved; } - private void initializeMappingMongoConverter(MappingMongoConverter converter) { - converter.setMongo(this.mongoDbFactory.getMongo()); - converter.setDefaultDatabase(this.mongoDbFactory.getDatabaseName()); - } - /** * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification * {@link DBObject} and executes that against the {@link DBCollection}. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/AbstractMongoConfiguration.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/AbstractMongoConfiguration.java index ef3183d40..c69359086 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/AbstractMongoConfiguration.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/AbstractMongoConfiguration.java @@ -31,7 +31,6 @@ import org.springframework.data.document.mongodb.MongoTemplate; import org.springframework.data.document.mongodb.convert.MappingMongoConverter; import org.springframework.data.document.mongodb.mapping.Document; import org.springframework.data.document.mongodb.mapping.MongoMappingContext; -import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator; import org.springframework.data.mapping.context.MappingContextAwareBeanPostProcessor; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -39,29 +38,27 @@ import org.springframework.util.StringUtils; @Configuration public abstract class AbstractMongoConfiguration { + public abstract String defaultDatabaseName(); + @Bean public abstract Mongo mongo() throws Exception; @Bean public abstract MongoTemplate mongoTemplate() throws Exception; - public String defaultDatabaseName() { - return "db"; - } - @Bean public MongoDbFactory mongoDbFactory() throws Exception { return new MongoDbFactoryBean(mongo(), defaultDatabaseName()); } - public String getMappingBasePackage() { + public String mappingBasePackage() { return ""; } @Bean public MongoMappingContext mongoMappingContext() throws ClassNotFoundException, LinkageError { MongoMappingContext mappingContext = new MongoMappingContext(); - String basePackage = getMappingBasePackage(); + String basePackage = mappingBasePackage(); if (StringUtils.hasText(basePackage)) { ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false); componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); @@ -78,8 +75,7 @@ public abstract class AbstractMongoConfiguration { @Bean public MappingMongoConverter mappingMongoConverter() throws Exception { - MappingMongoConverter converter = new MappingMongoConverter(mongoMappingContext()); - converter.setMongo(mongo()); + MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(), mongoMappingContext()); afterMappingMongoConverterCreation(converter); return converter; } @@ -99,8 +95,4 @@ public abstract class AbstractMongoConfiguration { return bpp; } - @Bean MongoPersistentEntityIndexCreator mongoPersistentEntityIndexCreator() throws Exception { - MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mongoMappingContext(), mongoDbFactory()); - return indexCreator; - } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MappingMongoConverterParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MappingMongoConverterParser.java index 234ef8b2d..68467ef27 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MappingMongoConverterParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MappingMongoConverterParser.java @@ -92,16 +92,15 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser { converterBuilder.addConstructorArgReference(ctxRef); // Need a reference to a Mongo instance - String mongoRef = element.getAttribute("mongo-ref"); - if (!StringUtils.hasText(mongoRef)) { - mongoRef = MONGO; + String dbFactoryRef = element.getAttribute("db-factory-ref"); + if (!StringUtils.hasText(dbFactoryRef)) { + dbFactoryRef = DB_FACTORY; } - converterBuilder.addPropertyReference("mongo", mongoRef); + converterBuilder.addPropertyReference("mongoDbFactory", dbFactoryRef); try { registry.getBeanDefinition(INDEX_HELPER); } catch (NoSuchBeanDefinitionException ignored) { - String dbFactoryRef = element.getAttribute("db-factory-ref"); if (!StringUtils.hasText(dbFactoryRef)) { dbFactoryRef = DB_FACTORY; } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java index ab40730fc..534a8554c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java @@ -87,9 +87,9 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { Element mongoEl = DomUtils.getChildElementByTagName(element, "mongo"); if (null != mongoEl) { String overrideHost = mongoEl.getAttribute("host"); - mongoBuilder.addPropertyValue("host", (overrideHost != null ? overrideHost : host)); + mongoBuilder.addPropertyValue("host", (StringUtils.hasText(overrideHost) ? overrideHost : host)); String overridePort = mongoEl.getAttribute("port"); - mongoBuilder.addPropertyValue("port", (overridePort != null ? overridePort : port)); + mongoBuilder.addPropertyValue("port", (StringUtils.hasText(overridePort) ? overridePort : port)); new MongoParser().parseOptions(parserContext, mongoEl, mongoBuilder); } registry.registerBeanDefinition(MONGO, mongoBuilder.getBeanDefinition()); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java index 604fdfb16..d13477095 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/convert/MappingMongoConverter.java @@ -38,7 +38,6 @@ import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBObject; import com.mongodb.DBRef; -import com.mongodb.Mongo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.bson.types.ObjectId; @@ -54,6 +53,7 @@ import org.springframework.core.convert.converter.ConverterFactory; import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.document.mongodb.MongoDbFactory; import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity; import org.springframework.data.document.mongodb.mapping.MongoPersistentProperty; import org.springframework.data.mapping.AssociationHandler; @@ -68,22 +68,23 @@ import org.springframework.data.util.TypeInformation; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.util.StringUtils; /** * {@link MongoConverter} that uses a {@link MappingContext} to do sophisticated mapping of domain objects to * {@link DBObject}. - * + * * @author Jon Brisbin * @author Oliver Gierke */ public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware, InitializingBean { public static final String CUSTOM_TYPE_KEY = "_class"; - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings({"unchecked"}) private static final List> MONGO_TYPES = Arrays.asList(Number.class, Date.class, String.class, DBObject.class); - private static final List> VALID_ID_TYPES = Arrays.asList(new Class[] { ObjectId.class, String.class, - BigInteger.class, byte[].class }); + private static final List> VALID_ID_TYPES = Arrays.asList(new Class[]{ObjectId.class, String.class, + BigInteger.class, byte[].class}); protected static final Log log = LogFactory.getLog(MappingMongoConverter.class); protected final GenericConversionService conversionService = ConversionServiceFactory @@ -93,12 +94,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App protected SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); protected ApplicationContext applicationContext; protected boolean useFieldAccessOnly = true; - protected Mongo mongo; - protected String defaultDatabase; + protected MongoDbFactory mongoDbFactory; + + public MappingMongoConverter(MongoDbFactory mongoDbFactory, MappingContext, MongoPersistentProperty> mappingContext) { + this.mongoDbFactory = mongoDbFactory; + this.mappingContext = mappingContext; + } /** * Creates a new {@link MappingMongoConverter} with the given {@link MappingContext}. - * + * * @param mappingContext */ public MappingMongoConverter( @@ -110,7 +115,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Add custom {@link Converter} or {@link ConverterFactory} instances to be used that will take presidence over * metadata driven conversion between of objects to/from DBObject - * + * * @param converters */ public void setCustomConverters(Set converters) { @@ -124,7 +129,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Inspects the given {@link Converter} for the types it can convert and registers the pair for custom type conversion * in case the target type is a Mongo basic type. - * + * * @param converter */ private void registerConverter(Object converter) { @@ -165,12 +170,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return mappingContext; } - public void setMongo(Mongo mongo) { - this.mongo = mongo; - } - - public void setDefaultDatabase(String defaultDatabase) { - this.defaultDatabase = defaultDatabase; + public void setMongoDbFactory(MongoDbFactory mongoDbFactory) { + this.mongoDbFactory = mongoDbFactory; } public boolean isUseFieldAccessOnly() { @@ -246,7 +247,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App spelCtx.setBeanResolver(new BeanFactoryResolver(applicationContext)); } if (!(dbo instanceof BasicDBList)) { - String[] keySet = dbo.keySet().toArray(new String[] {}); + String[] keySet = dbo.keySet().toArray(new String[]{}); for (String key : keySet) { spelCtx.setVariable(key, dbo.get(key)); } @@ -255,32 +256,32 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App final List ctorParamNames = new ArrayList(); final MongoPersistentProperty idProperty = entity.getIdProperty(); final S instance = constructInstance(entity, new PreferredConstructor.ParameterValueProvider() { - @SuppressWarnings("unchecked") - public T getParameterValue(PreferredConstructor.Parameter parameter) { - String name = parameter.getName(); - TypeInformation type = parameter.getType(); - Class rawType = parameter.getRawType(); - String key = idProperty == null ? name : idProperty.getName().equals(name) ? idProperty.getKey() : name; - Object obj = dbo.get(key); + @SuppressWarnings("unchecked") + public T getParameterValue(PreferredConstructor.Parameter parameter) { + String name = parameter.getName(); + TypeInformation type = parameter.getType(); + Class rawType = parameter.getRawType(); + String key = idProperty == null ? name : idProperty.getName().equals(name) ? idProperty.getKey() : name; + Object obj = dbo.get(key); - ctorParamNames.add(name); - if (obj instanceof DBRef) { - return read(type, ((DBRef) obj).fetch()); - } else if (obj instanceof BasicDBList) { - BasicDBList objAsDbList = (BasicDBList) obj; - List l = unwrapList(objAsDbList, type); - return conversionService.convert(l, rawType); - } else if (obj instanceof DBObject) { - return read(type, ((DBObject) obj)); - } else if (null != obj && obj.getClass().isAssignableFrom(rawType)) { - return (T) obj; - } else if (null != obj) { - return conversionService.convert(obj, rawType); - } + ctorParamNames.add(name); + if (obj instanceof DBRef) { + return read(type, ((DBRef) obj).fetch()); + } else if (obj instanceof BasicDBList) { + BasicDBList objAsDbList = (BasicDBList) obj; + List l = unwrapList(objAsDbList, type); + return conversionService.convert(l, rawType); + } else if (obj instanceof DBObject) { + return read(type, ((DBObject) obj)); + } else if (null != obj && obj.getClass().isAssignableFrom(rawType)) { + return (T) obj; + } else if (null != obj) { + return conversionService.convert(obj, rawType); + } - return null; - } - }, spelCtx); + return null; + } + }, spelCtx); // Set properties not already set in the constructor entity.doWithProperties(new PropertyHandler() { @@ -325,7 +326,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Root entry method into write conversion. Adds a type discriminator to the {@link DBObject}. Shouldn't be called for * nested conversions. - * + * * @see org.springframework.data.document.mongodb.MongoWriter#write(java.lang.Object, com.mongodb.DBObject) */ public void write(final Object obj, final DBObject dbo) { @@ -345,7 +346,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Internal write conversion method which should be used for nested invocations. - * + * * @param obj * @param dbo */ @@ -471,7 +472,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App setConversionService(conversionService); } - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings({"unchecked"}) protected void writePropertyInternal(MongoPersistentProperty prop, Object obj, DBObject dbo) { org.springframework.data.document.mongodb.mapping.DBRef dbref = prop.getField().getAnnotation( org.springframework.data.document.mongodb.mapping.DBRef.class); @@ -580,16 +581,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } } } - + /** * Writes the given simple value to the given {@link DBObject}. Will store enum names for enum values. - * + * * @param key * @param value * @param dbObject */ private void writeSimpleInternal(String key, Object value, DBObject dbObject) { - + Object valueToSet = value.getClass().isEnum() ? ((Enum) value).name() : value; dbObject.put(key, valueToSet); } @@ -619,17 +620,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } String dbname = dbref.db(); - if ("".equals(dbname)) { - dbname = defaultDatabase; - } - - DB db = mongo.getDB(dbname); + DB db = StringUtils.hasText(dbname) ? mongoDbFactory.getMongo().getDB(dbname) : mongoDbFactory.getDb(); return new DBRef(db, collection, id); } - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings({"unchecked"}) protected Object getValueInternal(MongoPersistentProperty prop, DBObject dbo, StandardEvaluationContext ctx, - String spelExpr) { + String spelExpr) { Object o; if (null != spelExpr) { @@ -716,7 +713,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Returns the type to be used to convert the DBObject given to. - * + * * @param dbObject * @return */ @@ -737,7 +734,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Inspects the a custom class definition stored inside the given {@link DBObject} and returns that in case it's a * subtype of the given basic one. - * + * * @param dbObject * @param basicType * @return diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java index 8269fb346..3e1730e75 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/MongoPersistentEntityIndexCreator.java @@ -142,8 +142,13 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener(); } - public String getMappingBasePackage() { + @Override + public String mappingBasePackage() { return "org.springframework.data.document.mongodb"; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateMappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateMappingTests.java index b58891fd3..0998a8e93 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateMappingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateMappingTests.java @@ -43,10 +43,6 @@ import com.mongodb.MongoException; @ContextConfiguration("classpath:template-mapping.xml") public class MongoTemplateMappingTests { - @Autowired - @Qualifier("mongoTemplate") - MongoTemplate template0; - @Autowired @Qualifier("mongoTemplate1") MongoTemplate template1; @@ -63,14 +59,6 @@ public class MongoTemplateMappingTests { template1.dropCollection(template1.getCollectionName(Person.class)); } - @Test - public void insertsEntityCorrectly0() throws Exception { - - addAndRetrievePerson(template0); - checkPersonPersisted(template0); - - } - @Test public void insertsEntityCorrectly1() throws Exception { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateTests.java index d10dc05ae..57586b57f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/MongoTemplateTests.java @@ -15,20 +15,20 @@ */ package org.springframework.data.document.mongodb; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isOneOf; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertThat; -import static org.springframework.data.document.mongodb.query.Criteria.where; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; +import static org.springframework.data.document.mongodb.query.Criteria.*; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import com.mongodb.DBCollection; +import com.mongodb.DBObject; +import com.mongodb.Mongo; +import com.mongodb.MongoException; +import com.mongodb.WriteResult; import org.bson.types.ObjectId; import org.junit.Assert; import org.junit.Before; @@ -52,15 +52,9 @@ import org.springframework.data.document.mongodb.query.Update; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoException; -import com.mongodb.WriteResult; - /** * Integration test for {@link MongoTemplate}. - * + * * @author Oliver Gierke * @author Thomas Risberg */ diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/TestMongoConfiguration.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/TestMongoConfiguration.java index 5d5390579..c95f62cff 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/TestMongoConfiguration.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/TestMongoConfiguration.java @@ -5,15 +5,19 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import com.mongodb.Mongo; import org.springframework.context.annotation.Bean; import org.springframework.core.convert.converter.Converter; import org.springframework.data.document.mongodb.config.AbstractMongoConfiguration; import org.springframework.data.document.mongodb.convert.MappingMongoConverter; -import com.mongodb.Mongo; - public class TestMongoConfiguration extends AbstractMongoConfiguration { + @Override + public String defaultDatabaseName() { + return "database"; + } + @Bean public Mongo mongo() throws Exception { return new Mongo("localhost", 27017); @@ -21,24 +25,21 @@ public class TestMongoConfiguration extends AbstractMongoConfiguration { @Bean public MongoTemplate mongoTemplate() throws Exception { - return new MongoTemplate(mongo(), "database", mappingMongoConverter()); + return new MongoTemplate(mongoDbFactory()); } @Override - public String getMappingBasePackage() { + public String mappingBasePackage() { return "org.springframework.data.document.mongodb.mapping"; } @Override - protected void afterMappingMongoConverterCreation( - MappingMongoConverter converter) { - super.afterMappingMongoConverterCreation(converter); + protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) { Set> converterList = new HashSet>(); converterList.add(new org.springframework.data.document.mongodb.PersonReadConverter()); converterList.add(new org.springframework.data.document.mongodb.PersonWriteConverter()); converter.setCustomConverters(converterList); } - - + } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/convert/CustomConvertersUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/convert/CustomConvertersUnitTests.java index 14bdbcfd9..35cf3f54b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/convert/CustomConvertersUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/convert/CustomConvertersUnitTests.java @@ -20,6 +20,8 @@ import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.HashSet; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; import org.hamcrest.CoreMatchers; import org.junit.Assert; import org.junit.Before; @@ -30,17 +32,13 @@ import org.mockito.runners.MockitoJUnitRunner; import org.springframework.core.convert.converter.Converter; import org.springframework.data.annotation.Id; import org.springframework.data.document.mongodb.mapping.MongoMappingContext; -import org.springframework.data.document.mongodb.mapping.MongoMappingContext; import org.springframework.data.document.mongodb.mapping.MongoPersistentEntity; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; - /** * Test case to verify correct usage of custom {@link Converter} implementations to be used. - * - * @see DATADOC-101 + * * @author Oliver Gierke + * @see DATADOC-101 */ @RunWith(MockitoJUnitRunner.class) public class CustomConvertersUnitTests { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedAppConfig.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedAppConfig.java index dd3bbbd63..1e6b610a9 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedAppConfig.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/GeoIndexedAppConfig.java @@ -2,8 +2,6 @@ package org.springframework.data.document.mongodb.mapping; import com.mongodb.Mongo; import org.springframework.context.annotation.Bean; -import org.springframework.data.document.mongodb.MongoDbFactory; -import org.springframework.data.document.mongodb.MongoDbFactoryBean; import org.springframework.data.document.mongodb.MongoTemplate; import org.springframework.data.document.mongodb.config.AbstractMongoConfiguration; @@ -12,19 +10,19 @@ public class GeoIndexedAppConfig extends AbstractMongoConfiguration { public static String GEO_DB = "geodb"; public static String GEO_COLLECTION = "geolocation"; + @Override + public String defaultDatabaseName() { + return GEO_DB; + } + @Bean public Mongo mongo() throws Exception { return new Mongo("localhost"); } - @Bean - public MongoDbFactory mongoDbFactory() throws Exception { - return new MongoDbFactoryBean(mongo(), GEO_DB); - } - @Bean public MongoTemplate mongoTemplate() throws Exception { - return new MongoTemplate(mongoDbFactory(), mappingMongoConverter()); + return new MongoTemplate(mongoDbFactory()); } public String getMappingBasePackage() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java index 8b1a6e147..670b2def5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingTests.java @@ -78,7 +78,7 @@ public class MappingTests { } applicationContext = new ClassPathXmlApplicationContext("/mapping.xml"); template = applicationContext.getBean(MongoTemplate.class); - mappingContext = applicationContext.getBean(MongoMappingContext.class); + mappingContext = (MongoMappingContext) template.getMappingContext(); } @Test diff --git a/spring-data-mongodb/src/test/resources/infrastructure.xml b/spring-data-mongodb/src/test/resources/infrastructure.xml index 89bd0e6c6..88b5112a2 100644 --- a/spring-data-mongodb/src/test/resources/infrastructure.xml +++ b/spring-data-mongodb/src/test/resources/infrastructure.xml @@ -1,23 +1,20 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> - - - - + + + + - - - - - - - - - - - + + + + + + + + diff --git a/spring-data-mongodb/src/test/resources/mapping.xml b/spring-data-mongodb/src/test/resources/mapping.xml index fbb230cd9..9cef168d8 100644 --- a/spring-data-mongodb/src/test/resources/mapping.xml +++ b/spring-data-mongodb/src/test/resources/mapping.xml @@ -1,18 +1,16 @@ - - + + + + + - - - - - - + diff --git a/spring-data-mongodb/src/test/resources/template-mapping.xml b/spring-data-mongodb/src/test/resources/template-mapping.xml index a9c1ff2ae..d0c19805b 100644 --- a/spring-data-mongodb/src/test/resources/template-mapping.xml +++ b/spring-data-mongodb/src/test/resources/template-mapping.xml @@ -7,13 +7,8 @@ - + - - - - -