From 5b57b40274b2c9dfc9a88f00ec858704d600d9d7 Mon Sep 17 00:00:00 2001 From: "J. Brisbin" Date: Thu, 19 May 2011 08:44:26 -0500 Subject: [PATCH] Added namespace parser for MongoDbFactory, made changes to getting mapping stuff to use MongoDbFactory --- .../data/document/mongodb/MongoTemplate.java | 189 ++++-- .../config/AbstractMongoConfiguration.java | 28 +- .../document/mongodb/config/BeanNames.java | 30 + .../config/MappingMongoConverterParser.java | 28 +- .../mongodb/config/MongoDbFactoryParser.java | 103 +++ .../document/mongodb/config/MongoParser.java | 6 +- .../config/MongoRepositoryConfigParser.java | 2 +- .../MongoRepositoryNamespaceHandler.java | 3 +- .../MongoPersistentEntityIndexCreator.java | 52 +- .../event/MongoMappingEventPublisher.java | 43 ++ .../mongodb/config/spring-mongo-1.0.xsd | 590 ++++++++++-------- .../mongodb/mapping/GeoIndexedAppConfig.java | 12 +- .../mapping/MongoMappingContextUnitTests.java | 24 +- .../src/test/resources/mapping.xml | 10 +- .../config/MongoNamespaceTests-context.xml | 66 +- ...rsonRepositoryIntegrationTests-context.xml | 48 +- ...MongoNamespaceIntegrationTests-context.xml | 39 +- .../src/test/resources/template-mapping.xml | 2 +- 18 files changed, 789 insertions(+), 486 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/BeanNames.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/event/MongoMappingEventPublisher.java 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 44ed454ad..b38b6e377 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 @@ -50,6 +50,7 @@ import org.springframework.data.document.mongodb.convert.MappingMongoConverter; import org.springframework.data.document.mongodb.convert.MongoConverter; import org.springframework.data.document.mongodb.convert.SimpleMongoConverter; 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.MongoPersistentProperty; import org.springframework.data.document.mongodb.mapping.event.AfterConvertEvent; @@ -58,6 +59,7 @@ import org.springframework.data.document.mongodb.mapping.event.AfterSaveEvent; import org.springframework.data.document.mongodb.mapping.event.BeforeConvertEvent; import org.springframework.data.document.mongodb.mapping.event.BeforeSaveEvent; import org.springframework.data.document.mongodb.mapping.event.MongoMappingEvent; +import org.springframework.data.document.mongodb.mapping.event.MongoMappingEventPublisher; import org.springframework.data.document.mongodb.query.Query; import org.springframework.data.document.mongodb.query.QueryMapper; import org.springframework.data.document.mongodb.query.Update; @@ -69,7 +71,7 @@ import org.springframework.util.Assert; /** * Primary implementation of {@link MongoOperations}. - * + * * @author Thomas Risberg * @author Graeme Rocher * @author Mark Pollack @@ -108,7 +110,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Constructor used for a basic template configuration - * + * * @param mongo * @param databaseName */ @@ -119,7 +121,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Constructor used for a template configuration with a custom * {@link org.springframework.data.document.mongodb.convert.MongoConverter} - * + * * @param mongo * @param databaseName * @param mongoConverter @@ -130,7 +132,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Constructor used for a basic template configuration - * + * * @param mongoDbFactory */ public MongoTemplate(MongoDbFactory mongoDbFactory) { @@ -139,16 +141,32 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Constructor used for a basic template configuration - * + * * @param mongoDbFactory * @param mongoConverter */ public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) { + this(mongoDbFactory, mongoConverter, null, null); + } + /** + * Constructor used for a template configuration with a custom {@link MongoConverter} and with a specific + * {@link com.mongodb.WriteConcern} to be used for all database write operations + * + * @param mongoDbFactory + * @param mongoConverter + * @param writeConcern + * @param writeResultChecking + */ + MongoTemplate(MongoDbFactory mongoDbFactory, + MongoConverter mongoConverter, + WriteConcern writeConcern, + WriteResultChecking writeResultChecking) { Assert.notNull(mongoDbFactory); this.mongoDbFactory = mongoDbFactory; this.mongoConverter = mongoConverter == null ? getDefaultMongoConverter() : mongoConverter; + this.writeConcern = writeConcern; if (this.mongoConverter instanceof MappingMongoConverter) { initializeMappingMongoConverter((MappingMongoConverter) this.mongoConverter); @@ -157,6 +175,14 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher this.mappingContext = this.mongoConverter.getMappingContext(); this.mapper = new QueryMapper(this.mongoConverter); + if (writeResultChecking != null) { + this.writeResultChecking = writeResultChecking; + } + + if (this.mappingContext instanceof MongoMappingContext) { + this.eventPublisher = new MongoMappingEventPublisher((MongoMappingContext) mappingContext, mongoDbFactory); + } + } private final MongoConverter getDefaultMongoConverter() { @@ -172,7 +198,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Returns the default {@link org.springframework.data.document.mongodb.convert.MongoConverter}. - * + * * @return */ public MongoConverter getConverter() { @@ -181,7 +207,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Returns the {@link org.springframework.data.document.mongodb.MongoDbFactory}. - * + * * @return */ public MongoDbFactory getDbFactory() { @@ -260,6 +286,71 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher } } + /** + * Central callback executing method to do queries against the datastore that requires reading a single object from a + * collection of objects. It will take the following steps + *
    + *
  1. Execute the given {@link ConnectionCallback} for a {@link DBObject}.
  2. + *
  3. Apply the given {@link DbObjectCallback} to each of the {@link DBObject}s to obtain the result.
  4. + *
      + * + * @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 + * @return + */ + private T execute(CollectionCallback collectionCallback, DbObjectCallback objectCallback, + String collectionName) { + + try { + T result = objectCallback.doWith(collectionCallback.doInCollection(getCollection(collectionName))); + return result; + } catch (RuntimeException e) { + throw potentiallyConvertRuntimeException(e); + } + } + + /** + * Central callback executing method to do queries against the datastore that requires reading a collection of + * objects. It will take the following steps + *
        + *
      1. Execute the given {@link ConnectionCallback} for a {@link DBCursor}.
      2. + *
      3. Prepare that {@link DBCursor} with the given {@link CursorPreparer} (will be skipped if {@link CursorPreparer} + * is {@literal null}
      4. + *
      5. Iterate over the {@link DBCursor} and applies the given {@link DbObjectCallback} to each of the + * {@link DBObject}s collecting the actual result {@link List}.
      6. + *
          + * + * @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 + * @return + */ + private List executeEach(CollectionCallback collectionCallback, CursorPreparer preparer, + DbObjectCallback objectCallback, String collectionName) { + + try { + DBCursor cursor = collectionCallback.doInCollection(getCollection(collectionName)); + + if (preparer != null) { + cursor = preparer.prepare(cursor); + } + + List result = new ArrayList(); + + for (DBObject object : cursor) { + result.add(objectCallback.doWith(object)); + } + + return result; + } catch (RuntimeException e) { + throw potentiallyConvertRuntimeException(e); + } + } + /* (non-Javadoc) * @see org.springframework.data.document.mongodb.MongoOperations#executeInSession(org.springframework.data.document.mongodb.DBCallback) */ @@ -681,7 +772,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher } protected WriteResult doUpdate(final String collectionName, final Query query, final Update update, - final Class entityClass, final boolean upsert, final boolean multi) { + final Class entityClass, final boolean upsert, final boolean multi) { return execute(collectionName, new CollectionCallback() { public WriteResult doInCollection(DBCollection collection) throws MongoException, DataAccessException { @@ -808,7 +899,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Create the specified collection using the provided options - * + * * @param collectionName * @param collectionOptions * @return the collection that was created @@ -827,15 +918,11 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * Map the results of an ad-hoc query on the default MongoDB collection to an object using the template's converter *

          * The query document is specified as a standard DBObject and so is the fields specification. - * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a record - * @param fields - * the document that specifies the fields to be returned - * @param targetClass - * the parameterized type of the returned list. + * + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param targetClass the parameterized type of the returned list. * @return the List of converted objects. */ protected T doFindOne(String collectionName, DBObject query, DBObject fields, Class targetClass) { @@ -856,22 +943,17 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * The query document is specified as a standard DBObject and so is the fields specification. *

          * Can be overridden by subclasses. - * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a record - * @param fields - * the document that specifies the fields to be returned - * @param targetClass - * the parameterized type of the returned list. - * @param preparer - * allows for customization of the DBCursor used when iterating over the result set, (apply limits, skips and - * so on). + * + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param targetClass the parameterized type of the returned list. + * @param preparer allows for customization of the DBCursor used when iterating over the result set, (apply limits, skips and + * so on). * @return the List of converted objects. */ protected List doFind(String collectionName, DBObject query, DBObject fields, Class targetClass, - CursorPreparer preparer) { + CursorPreparer preparer) { MongoPersistentEntity entity = mappingContext.getPersistentEntity(targetClass); if (LOGGER.isDebugEnabled()) { LOGGER.debug("find using query: " + query + " fields: " + fields + " for class: " + targetClass @@ -885,17 +967,11 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * Map the results of an ad-hoc query on the default MongoDB collection to a List using the template's converter. *

          * The query document is specified as a standard DBObject and so is the fields specification. - * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a record - * @param fields - * the document that specifies the fields to be returned - * @param targetClass - * the parameterized type of the returned list. - * @param reader - * the MongoReader to convert from DBObject to an object. + * + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param fields the document that specifies the fields to be returned + * @param targetClass the parameterized type of the returned list. * @return the List of converted objects. */ protected List doFind(String collectionName, DBObject query, DBObject fields, Class targetClass) { @@ -930,19 +1006,14 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher * The first document that matches the query is returned and also removed from the collection in the database. *

          * The query document is specified as a standard DBObject and so is the fields specification. - * - * @param collectionName - * name of the collection to retrieve the objects from - * @param query - * the query document that specifies the criteria used to find a record - * @param targetClass - * the parameterized type of the returned list. - * @param reader - * the MongoReader to convert from DBObject to an object. + * + * @param collectionName name of the collection to retrieve the objects from + * @param query the query document that specifies the criteria used to find a record + * @param targetClass the parameterized type of the returned list. * @return the List of converted objects. */ protected T doFindAndRemove(String collectionName, DBObject query, DBObject fields, DBObject sort, - Class targetClass) { + Class targetClass) { MongoReader readerToUse = this.mongoConverter; if (LOGGER.isDebugEnabled()) { LOGGER.debug("findAndRemove using query: " + query + " fields: " + fields + " sort: " + sort + " for class: " @@ -979,7 +1050,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Populates the id property of the saved object, if it's not set already. - * + * * @param savedObject * @param id */ @@ -1165,7 +1236,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Tries to convert the given {@link RuntimeException} into a {@link DataAccessException} but returns the original * exception if the conversation failed. Thus allows safe rethrowing of the return value. - * + * * @param ex * @return */ @@ -1182,7 +1253,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification * {@link DBObject} and executes that against the {@link DBCollection}. - * + * * @author Oliver Gierke * @author Thomas Risberg */ @@ -1216,7 +1287,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification * {@link DBObject} and executes that against the {@link DBCollection}. - * + * * @author Oliver Gierke * @author Thomas Risberg */ @@ -1247,7 +1318,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Simple {@link CollectionCallback} that takes a query {@link DBObject} plus an optional fields specification * {@link DBObject} and executes that against the {@link DBCollection}. - * + * * @author Thomas Risberg */ private static class FindAndRemoveCallback implements CollectionCallback { @@ -1271,7 +1342,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Simple internal callback to allow operations on a {@link DBObject}. - * + * * @author Oliver Gierke */ @@ -1283,7 +1354,7 @@ public class MongoTemplate implements MongoOperations, ApplicationEventPublisher /** * Simple {@link DbObjectCallback} that will transform {@link DBObject} into the given target type using the given * {@link MongoReader}. - * + * * @author Oliver Gierke */ private class ReadDbObjectCallback implements DbObjectCallback { 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 60c1255dc..ef3183d40 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 @@ -18,12 +18,15 @@ package org.springframework.data.document.mongodb.config; import java.util.HashSet; import java.util.Set; +import com.mongodb.Mongo; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.Configuration; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.data.annotation.Persistent; +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.convert.MappingMongoConverter; import org.springframework.data.document.mongodb.mapping.Document; @@ -33,8 +36,6 @@ import org.springframework.data.mapping.context.MappingContextAwareBeanPostProce import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; -import com.mongodb.Mongo; - @Configuration public abstract class AbstractMongoConfiguration { @@ -44,6 +45,15 @@ public abstract class AbstractMongoConfiguration { @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() { return ""; } @@ -53,15 +63,13 @@ public abstract class AbstractMongoConfiguration { MongoMappingContext mappingContext = new MongoMappingContext(); String basePackage = getMappingBasePackage(); if (StringUtils.hasText(basePackage)) { - ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider( - false); + ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider(false); componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class)); Set> initialEntitySet = new HashSet>(); for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { - initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass() - .getClassLoader())); + initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), mappingContext.getClass().getClassLoader())); } mappingContext.setInitialEntitySet(initialEntitySet); } @@ -78,7 +86,7 @@ public abstract class AbstractMongoConfiguration { /** * Hook that allows post-processing after the MappingMongoConverter has been successfully created. - * + * * @param converter */ protected void afterMappingMongoConverterCreation(MappingMongoConverter converter) { @@ -91,10 +99,8 @@ public abstract class AbstractMongoConfiguration { return bpp; } - @Bean - MongoPersistentEntityIndexCreator mongoPersistentEntityIndexCreator() throws Exception { - MongoPersistentEntityIndexCreator indexCreator = new MongoPersistentEntityIndexCreator(mongoMappingContext(), - mongoTemplate()); + @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/BeanNames.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/BeanNames.java new file mode 100644 index 000000000..daa7820c9 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/BeanNames.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * 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.document.mongodb.config; + +/** + * @author Jon Brisbin + */ +public abstract class BeanNames { + + static final String MAPPING_CONTEXT = "mappingContext"; + static final String INDEX_HELPER = "indexCreationHelper"; + static final String MONGO = "mongo"; + static final String DB_FACTORY = "mongoDbFactory"; + static final String POST_PROCESSOR = "mappingContextAwareBeanPostProcessor"; + +} 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 21fe7deeb..234ef8b2d 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 @@ -16,23 +16,21 @@ package org.springframework.data.document.mongodb.config; +import static org.springframework.data.document.mongodb.config.BeanNames.*; + import java.util.List; import java.util.Set; import org.springframework.beans.BeanMetadataElement; -import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.RuntimeBeanNameReference; import org.springframework.beans.factory.config.RuntimeBeanReference; -import org.springframework.beans.factory.parsing.CompositeComponentDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.ManagedList; -import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.ManagedSet; import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; @@ -54,12 +52,6 @@ import org.w3c.dom.Element; */ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser { - static final String MAPPING_CONTEXT = "mappingContext"; - - private static final String INDEX_HELPER = "indexCreationHelper"; - private static final String TEMPLATE = "mongoTemplate"; - private static final String POST_PROCESSOR = "mappingContextAwareBeanPostProcessor"; - private static final String BASE_PACKAGE = "base-package"; @Override @@ -101,17 +93,21 @@ public class MappingMongoConverterParser extends AbstractBeanDefinitionParser { // Need a reference to a Mongo instance String mongoRef = element.getAttribute("mongo-ref"); - converterBuilder.addPropertyReference("mongo", StringUtils.hasText(mongoRef) ? mongoRef : "mongo"); + if (!StringUtils.hasText(mongoRef)) { + mongoRef = MONGO; + } + converterBuilder.addPropertyReference("mongo", mongoRef); try { registry.getBeanDefinition(INDEX_HELPER); } catch (NoSuchBeanDefinitionException ignored) { - String templateRef = element.getAttribute("mongo-template-ref"); - BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder - .genericBeanDefinition(MongoPersistentEntityIndexCreator.class); + String dbFactoryRef = element.getAttribute("db-factory-ref"); + if (!StringUtils.hasText(dbFactoryRef)) { + dbFactoryRef = DB_FACTORY; + } + BeanDefinitionBuilder indexHelperBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoPersistentEntityIndexCreator.class); indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(ctxRef)); - indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(StringUtils.hasText(templateRef) ? templateRef - : TEMPLATE)); + indexHelperBuilder.addConstructorArgValue(new RuntimeBeanReference(dbFactoryRef)); registry.registerBeanDefinition(INDEX_HELPER, indexHelperBuilder.getBeanDefinition()); } 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 new file mode 100644 index 000000000..ab40730fc --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoDbFactoryParser.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * 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.document.mongodb.config; + +import static org.springframework.data.document.mongodb.config.BeanNames.*; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.document.mongodb.MongoDbFactoryBean; +import org.springframework.data.document.mongodb.MongoFactoryBean; +import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +/** + * @author Jon Brisbin + */ +public class MongoDbFactoryParser extends AbstractBeanDefinitionParser { + + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) throws BeanDefinitionStoreException { + String id = element.getAttribute("id"); + if (!StringUtils.hasText(id)) { + id = DB_FACTORY; + } + return id; + } + + @Override + protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { + BeanDefinitionRegistry registry = parserContext.getRegistry(); + BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoDbFactoryBean.class); + + // Host/Port used in this and the mongoFactory + String host = element.getAttribute("host"); + if (!StringUtils.hasText(host)) { + host = "localhost"; + } + dbFactoryBuilder.addPropertyValue("host", host); + String port = element.getAttribute("port"); + if (!StringUtils.hasText(port)) { + port = "27017"; + } + dbFactoryBuilder.addPropertyValue("port", port); + + // Username/Password not always used (but is in CloudFoundry + String username = element.getAttribute("username"); + if (StringUtils.hasText(username)) { + dbFactoryBuilder.addPropertyValue("username", username); + } + String password = element.getAttribute("password"); + if (StringUtils.hasText(password)) { + dbFactoryBuilder.addPropertyValue("password", password); + } + + // Database name + String db = element.getAttribute("db"); + if (!StringUtils.hasText(db)) { + db = "db"; + } + dbFactoryBuilder.addPropertyValue("databaseName", db); + + // Create or reference a MongoFactory instance. + // Also respect embedded "mongo:mongo" definitions. + String mongoRef = element.getAttribute("mongo-ref"); + if (!StringUtils.hasText(mongoRef)) { + BeanDefinitionBuilder mongoBuilder = BeanDefinitionBuilder.genericBeanDefinition(MongoFactoryBean.class); + Element mongoEl = DomUtils.getChildElementByTagName(element, "mongo"); + if (null != mongoEl) { + String overrideHost = mongoEl.getAttribute("host"); + mongoBuilder.addPropertyValue("host", (overrideHost != null ? overrideHost : host)); + String overridePort = mongoEl.getAttribute("port"); + mongoBuilder.addPropertyValue("port", (overridePort != null ? overridePort : port)); + new MongoParser().parseOptions(parserContext, mongoEl, mongoBuilder); + } + registry.registerBeanDefinition(MONGO, mongoBuilder.getBeanDefinition()); + mongoRef = MONGO; + } + dbFactoryBuilder.addPropertyValue("mongo", new RuntimeBeanReference(mongoRef)); + + return dbFactoryBuilder.getRawBeanDefinition(); + } + +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoParser.java index 4d029d6e1..2b9989a3a 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoParser.java @@ -29,7 +29,7 @@ import org.w3c.dom.Element; /** * Parser for <mongo;gt; definitions. If no name - * + * * @author Mark Pollack */ public class MongoParser extends AbstractSingleBeanDefinitionParser { @@ -51,12 +51,12 @@ public class MongoParser extends AbstractSingleBeanDefinitionParser { /** * Parses the options sub-element. Populates the given attribute factory with the proper attributes. - * + * * @param element * @param attrBuilder * @return true if parsing actually occured, false otherwise */ - private boolean parseOptions(ParserContext parserContext, Element element, BeanDefinitionBuilder mongoBuilder) { + boolean parseOptions(ParserContext parserContext, Element element, BeanDefinitionBuilder mongoBuilder) { Element optionsElement = DomUtils.getChildElementByTagName(element, "options"); if (optionsElement == null) return false; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java index 94f39a1f2..7c6562028 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryConfigParser.java @@ -32,7 +32,7 @@ import org.w3c.dom.Element; public class MongoRepositoryConfigParser extends AbstractRepositoryConfigDefinitionParser { - private static final String MAPPING_CONTEXT_DEFAULT = MappingMongoConverterParser.MAPPING_CONTEXT; + private static final String MAPPING_CONTEXT_DEFAULT = BeanNames.MAPPING_CONTEXT; /* * (non-Javadoc) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryNamespaceHandler.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryNamespaceHandler.java index 0dc275879..875ea3070 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryNamespaceHandler.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/config/MongoRepositoryNamespaceHandler.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; /** * {@link org.springframework.beans.factory.xml.NamespaceHandler} for Mongo DB based repositories. - * + * * @author Oliver Gierke */ public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport { @@ -34,6 +34,7 @@ public class MongoRepositoryNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("repositories", new MongoRepositoryConfigParser()); registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser()); registerBeanDefinitionParser("mongo", new MongoParser()); + registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser()); registerBeanDefinitionParser("jmx", new MongoJmxParser()); } } 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 4bb80be71..8269fb346 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 @@ -22,16 +22,12 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import com.mongodb.BasicDBObject; -import com.mongodb.DBCollection; import com.mongodb.DBObject; -import com.mongodb.MongoException; import com.mongodb.util.JSON; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationListener; -import org.springframework.dao.DataAccessException; -import org.springframework.data.document.mongodb.CollectionCallback; -import org.springframework.data.document.mongodb.MongoTemplate; +import org.springframework.data.document.mongodb.MongoDbFactory; import org.springframework.data.document.mongodb.index.CompoundIndex; import org.springframework.data.document.mongodb.index.CompoundIndexes; import org.springframework.data.document.mongodb.index.GeoSpatialIndexed; @@ -47,7 +43,7 @@ import org.springframework.util.StringUtils; /** * Component that inspects {@link BasicMongoPersistentEntity} instances contained in the given * {@link MongoMappingContext} for indexing metadata and ensures the indexes to be available. - * + * * @author Jon Brisbin * @author Oliver Gierke */ @@ -57,13 +53,13 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener> classesSeen = Collections.newSetFromMap(new ConcurrentHashMap, Boolean>()); - private final MongoTemplate mongoTemplate; + private final MongoDbFactory mongoDbFactory; - public MongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoTemplate mongoTemplate) { + public MongoPersistentEntityIndexCreator(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) { - Assert.notNull(mongoTemplate); + Assert.notNull(mongoDbFactory); Assert.notNull(mappingContext); - this.mongoTemplate = mongoTemplate; + this.mongoDbFactory = mongoDbFactory; for (MongoPersistentEntity entity : mappingContext.getPersistentEntities()) { checkForIndexes(entity); @@ -131,7 +127,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener() { - public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException { - DBObject defObj; - if (null != def) { - defObj = (DBObject) JSON.parse(def); - } else { - defObj = new BasicDBObject(); - defObj.put(name, (direction == IndexDirection.ASCENDING ? 1 : -1)); - } - DBObject opts = new BasicDBObject(); - // opts.put("name", name + "_idx"); - opts.put("dropDups", dropDups); - opts.put("sparse", sparse); - opts.put("unique", unique); - collection.ensureIndex(defObj, opts); - return null; - } - }); + final boolean unique, final boolean dropDups, final boolean sparse) { + DBObject defObj; + if (null != def) { + defObj = (DBObject) JSON.parse(def); + } else { + defObj = new BasicDBObject(); + defObj.put(name, (direction == IndexDirection.ASCENDING ? 1 : -1)); + } + DBObject opts = new BasicDBObject(); + // opts.put("name", name + "_idx"); + opts.put("dropDups", dropDups); + opts.put("sparse", sparse); + opts.put("unique", unique); + mongoDbFactory.getDb().getCollection(collection).ensureIndex(defObj, opts); } + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/event/MongoMappingEventPublisher.java b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/event/MongoMappingEventPublisher.java new file mode 100644 index 000000000..d68641934 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/event/MongoMappingEventPublisher.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * 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.document.mongodb.mapping.event; + +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.document.mongodb.MongoDbFactory; +import org.springframework.data.document.mongodb.mapping.MongoMappingContext; +import org.springframework.data.document.mongodb.mapping.MongoPersistentEntityIndexCreator; +import org.springframework.data.mapping.event.MappingContextEvent; + +/** + * @author Jon Brisbin + */ +public class MongoMappingEventPublisher implements ApplicationEventPublisher { + + private MongoPersistentEntityIndexCreator indexCreator; + + public MongoMappingEventPublisher(MongoMappingContext mappingContext, MongoDbFactory mongoDbFactory) { + indexCreator = new MongoPersistentEntityIndexCreator(mappingContext, mongoDbFactory); + } + + public void publishEvent(ApplicationEvent event) { + if (event instanceof MappingContextEvent) { + indexCreator.onApplicationEvent((MappingContextEvent) event); + } + } + +} diff --git a/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd b/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd index 09b59efc4..59f3880b6 100644 --- a/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd +++ b/spring-data-mongodb/src/main/resources/org/springframework/data/document/mongodb/config/spring-mongo-1.0.xsd @@ -1,311 +1,379 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + The reference to a Mongo. Will default to 'mongo'. + + + + + + + + + + + - - - - - + + + + - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - The reference to a MongoTemplate. Will default to 'mongoTemplate'. - - - - - - - The reference to a MappingContext. Will pick up a bean named 'mappingContext' by default if available. - - - - + + + + + + + + - - - - - - - - - - - - - + + + + + The reference to a MongoTemplate. Will default to 'mongoTemplate'. + + + + + + + The reference to a MappingContext. Will pick up a bean named 'mappingContext' by default if available. + + + + - - - + + + + + + + + + + + + + + + + - - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + - - - - - + + + + - - - - - - The reference to a Mongo. Will default to 'mongo'. - - - - - - - The reference to a MappingContext. Will default to 'mappingContext'. - - - - - - - The reference to a MongoTemplate. Will default to 'mongoTemplate'. - - - - - + + + + + + The reference to a Mongo. Will default to 'mongo'. + + + + + + + The reference to a MappingContext. Will default to 'mappingContext'. + + + + + + + The reference to a MongoTemplate. Will default to 'mongoTemplate'. + + + + + - - - + + - - - - - + + + + - - - - + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - - - - + + + + + + - - - + + - - - - - - A reference to a custom converter. - - - - - - - + + + + + + A reference to a custom converter. + + + + + + + \ No newline at end of file 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 a4ea6fe92..dd3bbbd63 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 @@ -1,11 +1,12 @@ 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; -import com.mongodb.Mongo; - public class GeoIndexedAppConfig extends AbstractMongoConfiguration { public static String GEO_DB = "geodb"; @@ -16,9 +17,14 @@ public class GeoIndexedAppConfig extends AbstractMongoConfiguration { 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(mongo(), "geodb", mappingMongoConverter()); + return new MongoTemplate(mongoDbFactory(), mappingMongoConverter()); } public String getMappingBasePackage() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MongoMappingContextUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MongoMappingContextUnitTests.java index 656f91134..dadcdf4db 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MongoMappingContextUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MongoMappingContextUnitTests.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2011 by the original author(s). + * + * 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.document.mongodb.mapping; import java.util.Collections; @@ -7,20 +23,20 @@ import org.junit.Test; /** * Unit tests for {@link MongoMappingContext}. - * + * * @author Oliver Gierke */ public class MongoMappingContextUnitTests { @Test - public void addsSelfReferencingPersistentEntityCorrectly() { + public void addsSelfReferencingPersistentEntityCorrectly() throws Exception { MongoMappingContext context = new MongoMappingContext(); context.setInitialEntitySet(Collections.singleton(SampleClass.class)); context.afterPropertiesSet(); } - + public class SampleClass { - + Map children; } } diff --git a/spring-data-mongodb/src/test/resources/mapping.xml b/spring-data-mongodb/src/test/resources/mapping.xml index 600d4b404..fbb230cd9 100644 --- a/spring-data-mongodb/src/test/resources/mapping.xml +++ b/spring-data-mongodb/src/test/resources/mapping.xml @@ -5,14 +5,8 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd"> - - - - - - - - + + diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/config/MongoNamespaceTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/config/MongoNamespaceTests-context.xml index bc5e7c4a0..91be74b52 100644 --- a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/config/MongoNamespaceTests-context.xml +++ b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/config/MongoNamespaceTests-context.xml @@ -1,45 +1,43 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:mongo="http://www.springframework.org/schema/data/mongo" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - + - - - + + + + + - + - + - - - - - - - - - - + + + + + + + + - - - - + - - - - + + + + diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml index 8cd6df099..db602c671 100644 --- a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml +++ b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/PersonRepositoryIntegrationTests-context.xml @@ -1,38 +1,22 @@ + xmlns:mongo="http://www.springframework.org/schema/data/mongo" + 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 + http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd"> - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - + + + + + + + + + + diff --git a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/config/MongoNamespaceIntegrationTests-context.xml b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/config/MongoNamespaceIntegrationTests-context.xml index acf4c1d3b..b9757262f 100644 --- a/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/config/MongoNamespaceIntegrationTests-context.xml +++ b/spring-data-mongodb/src/test/resources/org/springframework/data/document/mongodb/repository/config/MongoNamespaceIntegrationTests-context.xml @@ -1,28 +1,23 @@ - - + xmlns:mongo="http://www.springframework.org/schema/data/mongo" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:repository="http://www.springframework.org/schema/data/repository" + xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd"> - - - - - - - - - - - + - - - + + + + + + + + + + diff --git a/spring-data-mongodb/src/test/resources/template-mapping.xml b/spring-data-mongodb/src/test/resources/template-mapping.xml index 8441112c3..a9c1ff2ae 100644 --- a/spring-data-mongodb/src/test/resources/template-mapping.xml +++ b/spring-data-mongodb/src/test/resources/template-mapping.xml @@ -7,7 +7,7 @@ - +