Compare commits
13 Commits
1.5.2.RELE
...
1.5.4.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7c3ef2aa8 | ||
|
|
3320e49c0b | ||
|
|
286efca52d | ||
|
|
92926befc9 | ||
|
|
703f24ae1c | ||
|
|
febe703954 | ||
|
|
440d16ebc6 | ||
|
|
11c2e90736 | ||
|
|
816a567f29 | ||
|
|
e35486759b | ||
|
|
b80c81f861 | ||
|
|
005d21c0b6 | ||
|
|
3c8b7a54d6 |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data.build</groupId>
|
||||
<artifactId>spring-data-parent</artifactId>
|
||||
<version>1.4.2.RELEASE</version>
|
||||
<version>1.4.4.RELEASE</version>
|
||||
<relativePath>../spring-data-build/parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.8.2.RELEASE</springdata.commons>
|
||||
<springdata.commons>1.8.4.RELEASE</springdata.commons>
|
||||
<mongo>2.12.1</mongo>
|
||||
<mongo.osgi>2.12.1</mongo.osgi>
|
||||
</properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Core</name>
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.5.2.RELEASE</version>
|
||||
<version>1.5.4.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
@@ -77,7 +77,7 @@
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- CDI -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
@@ -86,21 +86,21 @@
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>el-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
@@ -115,7 +115,7 @@
|
||||
<version>${validation}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.objenesis</groupId>
|
||||
<artifactId>objenesis</artifactId>
|
||||
@@ -129,23 +129,23 @@
|
||||
<version>4.2.0.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
<version>${slf4j}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -189,9 +189,14 @@
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
<properties>
|
||||
<property>
|
||||
<name>listener</name>
|
||||
<value>org.springframework.data.mongodb.test.util.CleanMongoDBJunitRunListener</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.data.mongodb.core;
|
||||
import static org.springframework.data.domain.Sort.Direction.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
@@ -41,6 +43,7 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
|
||||
private static final Double ONE = Double.valueOf(1);
|
||||
private static final Double MINUS_ONE = Double.valueOf(-1);
|
||||
private static final Collection<String> TWO_D_IDENTIFIERS = Arrays.asList("2d", "2dsphere");
|
||||
|
||||
private final MongoOperations mongoOperations;
|
||||
private final String collectionName;
|
||||
@@ -140,7 +143,7 @@ public class DefaultIndexOperations implements IndexOperations {
|
||||
|
||||
Object value = keyDbObject.get(key);
|
||||
|
||||
if ("2d".equals(value)) {
|
||||
if (TWO_D_IDENTIFIERS.contains(value)) {
|
||||
indexFields.add(IndexField.geo(key));
|
||||
} else {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -28,7 +28,7 @@ import com.mongodb.DBObject;
|
||||
* @author Oliver Gierke
|
||||
* @since 1.3
|
||||
*/
|
||||
class LimitOperation implements AggregationOperation {
|
||||
public class LimitOperation implements AggregationOperation {
|
||||
|
||||
private final long maxElements;
|
||||
|
||||
|
||||
@@ -76,6 +76,8 @@ import com.mongodb.DBRef;
|
||||
*/
|
||||
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
|
||||
|
||||
private static final String INCOMPATIBLE_TYPES = "Cannot convert %1$s of type %2$s into an instance of %3$s! Implement a custom Converter<%2$s, %3$s> and register it with the CustomConversions. Parent object was: %4$s";
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(MappingMongoConverter.class);
|
||||
|
||||
protected final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
|
||||
@@ -214,6 +216,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return (S) readMap(typeToUse, dbo, parent);
|
||||
}
|
||||
|
||||
if (dbo instanceof BasicDBList) {
|
||||
throw new MappingException(String.format(INCOMPATIBLE_TYPES, dbo, BasicDBList.class, typeToUse.getType(), parent));
|
||||
}
|
||||
|
||||
// Retrieve persistent entity info
|
||||
MongoPersistentEntity<S> persistentEntity = (MongoPersistentEntity<S>) mappingContext
|
||||
.getPersistentEntity(typeToUse);
|
||||
|
||||
@@ -73,7 +73,43 @@ public @interface CompoundIndex {
|
||||
boolean dropDups() default false;
|
||||
|
||||
/**
|
||||
* The name of the index to be created.
|
||||
* The name of the index to be created. <br />
|
||||
* <br />
|
||||
* The name will only be applied as is when defined on root level. For usage on nested or embedded structures the
|
||||
* provided name will be prefixed with the path leading to the entity. <br />
|
||||
* <br />
|
||||
* The structure below
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* @Document
|
||||
* class Root {
|
||||
* Hybrid hybrid;
|
||||
* Nested nested;
|
||||
* }
|
||||
*
|
||||
* @Document
|
||||
* @CompoundIndex(name = "compound_index", def = "{'h1': 1, 'h2': 1}")
|
||||
* class Hybrid {
|
||||
* String h1, h2;
|
||||
* }
|
||||
*
|
||||
* @CompoundIndex(name = "compound_index", def = "{'n1': 1, 'n2': 1}")
|
||||
* class Nested {
|
||||
* String n1, n2;
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* resolves in the following index structures
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* db.root.ensureIndex( { hybrid.h1: 1, hybrid.h2: 1 } , { name: "hybrid.compound_index" } )
|
||||
* db.root.ensureIndex( { nested.n1: 1, nested.n2: 1 } , { name: "nested.compound_index" } )
|
||||
* db.hybrid.ensureIndex( { h1: 1, h2: 1 } , { name: "compound_index" } )
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,41 @@ import java.lang.annotation.Target;
|
||||
public @interface GeoSpatialIndexed {
|
||||
|
||||
/**
|
||||
* Name of the property in the document that contains the [x, y] or radial coordinates to index.
|
||||
* Index name. <br />
|
||||
* <br />
|
||||
* The name will only be applied as is when defined on root level. For usage on nested or embedded structures the
|
||||
* provided name will be prefixed with the path leading to the entity. <br />
|
||||
* <br />
|
||||
* The structure below
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* @Document
|
||||
* class Root {
|
||||
* Hybrid hybrid;
|
||||
* Nested nested;
|
||||
* }
|
||||
*
|
||||
* @Document
|
||||
* class Hybrid {
|
||||
* @GeoSpatialIndexed(name="index") Point h1;
|
||||
* }
|
||||
*
|
||||
* class Nested {
|
||||
* @GeoSpatialIndexed(name="index") Point n1;
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* resolves in the following index structures
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* db.root.ensureIndex( { hybrid.h1: "2d" } , { name: "hybrid.index" } )
|
||||
* db.root.ensureIndex( { nested.n1: "2d" } , { name: "nested.index" } )
|
||||
* db.hybrid.ensureIndex( { h1: "2d" } , { name: "index" } )
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -58,7 +58,41 @@ public @interface Indexed {
|
||||
boolean dropDups() default false;
|
||||
|
||||
/**
|
||||
* Index name.
|
||||
* Index name. <br />
|
||||
* <br />
|
||||
* The name will only be applied as is when defined on root level. For usage on nested or embedded structures the
|
||||
* provided name will be prefixed with the path leading to the entity. <br />
|
||||
* <br />
|
||||
* The structure below
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* @Document
|
||||
* class Root {
|
||||
* Hybrid hybrid;
|
||||
* Nested nested;
|
||||
* }
|
||||
*
|
||||
* @Document
|
||||
* class Hybrid {
|
||||
* @Indexed(name="index") String h1;
|
||||
* }
|
||||
*
|
||||
* class Nested {
|
||||
* @Indexed(name="index") String n1;
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* resolves in the following index structures
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* db.root.ensureIndex( { hybrid.h1: 1 } , { name: "hybrid.index" } )
|
||||
* db.root.ensureIndex( { nested.n1: 1 } , { name: "nested.index" } )
|
||||
* db.hybrid.ensureIndex( { h1: 1} , { name: "index" } )
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
@@ -92,7 +91,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
Assert.notNull(document, "Given entity is not collection root.");
|
||||
|
||||
final List<IndexDefinitionHolder> indexInformation = new ArrayList<MongoPersistentEntityIndexResolver.IndexDefinitionHolder>();
|
||||
indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions("", root.getCollection(), root.getType()));
|
||||
indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions("", root.getCollection(), root));
|
||||
|
||||
final CycleGuard guard = new CycleGuard();
|
||||
|
||||
@@ -133,10 +132,11 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
private List<IndexDefinitionHolder> resolveIndexForClass(final Class<?> type, final String path,
|
||||
final String collection, final CycleGuard guard) {
|
||||
|
||||
final List<IndexDefinitionHolder> indexInformation = new ArrayList<MongoPersistentEntityIndexResolver.IndexDefinitionHolder>();
|
||||
indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions(path, collection, type));
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
|
||||
final List<IndexDefinitionHolder> indexInformation = new ArrayList<MongoPersistentEntityIndexResolver.IndexDefinitionHolder>();
|
||||
indexInformation.addAll(potentiallyCreateCompoundIndexDefinitions(path, collection, entity));
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
@@ -178,14 +178,13 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
}
|
||||
|
||||
private List<IndexDefinitionHolder> potentiallyCreateCompoundIndexDefinitions(String dotPath, String collection,
|
||||
Class<?> type) {
|
||||
MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (AnnotationUtils.findAnnotation(type, CompoundIndexes.class) == null
|
||||
&& AnnotationUtils.findAnnotation(type, CompoundIndex.class) == null) {
|
||||
if (entity.findAnnotation(CompoundIndexes.class) == null && entity.findAnnotation(CompoundIndex.class) == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return createCompoundIndexDefinitions(dotPath, collection, type);
|
||||
return createCompoundIndexDefinitions(dotPath, collection, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,21 +196,21 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
* @return
|
||||
*/
|
||||
protected List<IndexDefinitionHolder> createCompoundIndexDefinitions(String dotPath, String fallbackCollection,
|
||||
Class<?> type) {
|
||||
MongoPersistentEntity<?> entity) {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = new ArrayList<MongoPersistentEntityIndexResolver.IndexDefinitionHolder>();
|
||||
CompoundIndexes indexes = AnnotationUtils.findAnnotation(type, CompoundIndexes.class);
|
||||
CompoundIndexes indexes = entity.findAnnotation(CompoundIndexes.class);
|
||||
|
||||
if (indexes != null) {
|
||||
for (CompoundIndex index : indexes.value()) {
|
||||
indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index));
|
||||
indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity));
|
||||
}
|
||||
}
|
||||
|
||||
CompoundIndex index = AnnotationUtils.findAnnotation(type, CompoundIndex.class);
|
||||
CompoundIndex index = entity.findAnnotation(CompoundIndex.class);
|
||||
|
||||
if (index != null) {
|
||||
indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index));
|
||||
indexDefinitions.add(createCompoundIndexDefinition(dotPath, fallbackCollection, index, entity));
|
||||
}
|
||||
|
||||
return indexDefinitions;
|
||||
@@ -219,13 +218,13 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, String fallbackCollection,
|
||||
CompoundIndex index) {
|
||||
CompoundIndex index, MongoPersistentEntity<?> entity) {
|
||||
|
||||
CompoundIndexDefinition indexDefinition = new CompoundIndexDefinition(resolveCompoundIndexKeyFromStringDefinition(
|
||||
dotPath, index.def()));
|
||||
|
||||
if (!index.useGeneratedName()) {
|
||||
indexDefinition.named(index.name());
|
||||
indexDefinition.named(pathAwareIndexName(index.name(), dotPath, null));
|
||||
}
|
||||
|
||||
if (index.unique()) {
|
||||
@@ -296,7 +295,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
IndexDirection.ASCENDING.equals(index.direction()) ? Sort.Direction.ASC : Sort.Direction.DESC);
|
||||
|
||||
if (!index.useGeneratedName()) {
|
||||
indexDefinition.named(StringUtils.hasText(index.name()) ? index.name() : dotPath);
|
||||
indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persitentProperty));
|
||||
}
|
||||
|
||||
if (index.unique()) {
|
||||
@@ -338,7 +337,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
indexDefinition.withMin(index.min()).withMax(index.max());
|
||||
|
||||
if (!index.useGeneratedName()) {
|
||||
indexDefinition.named(StringUtils.hasText(index.name()) ? index.name() : persistentProperty.getName());
|
||||
indexDefinition.named(pathAwareIndexName(index.name(), dotPath, persistentProperty));
|
||||
}
|
||||
|
||||
indexDefinition.typed(index.type()).withBucketSize(index.bucketSize()).withAdditionalField(index.additionalField());
|
||||
@@ -346,6 +345,23 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
|
||||
return new IndexDefinitionHolder(dotPath, indexDefinition, collection);
|
||||
}
|
||||
|
||||
private String pathAwareIndexName(String indexName, String dotPath, MongoPersistentProperty property) {
|
||||
|
||||
String nameToUse = StringUtils.hasText(indexName) ? indexName : "";
|
||||
|
||||
if (!StringUtils.hasText(dotPath) || (property != null && dotPath.equals(property.getFieldName()))) {
|
||||
return StringUtils.hasText(nameToUse) ? nameToUse : dotPath;
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(dotPath)) {
|
||||
|
||||
nameToUse = StringUtils.hasText(nameToUse) ? (property != null ? dotPath.replace("." + property.getFieldName(),
|
||||
"") : dotPath) + "." + nameToUse : dotPath;
|
||||
}
|
||||
return nameToUse;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link CycleGuard} holds information about properties and the paths for accessing those. This information is used
|
||||
* to detect potential cycles within the references.
|
||||
|
||||
@@ -284,7 +284,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return countProjection ? operations.count(query, metadata.getJavaType()) : operations.findOne(query,
|
||||
metadata.getJavaType());
|
||||
metadata.getJavaType(), metadata.getCollectionName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.mongodb.core.index.IndexInfo;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultIndexOperations}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class DefaultIndexOperationsIntegrationTests {
|
||||
|
||||
static final DBObject GEO_SPHERE_2D = new BasicDBObject("loaction", "2dsphere");
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
DefaultIndexOperations indexOps;
|
||||
DBCollection collection;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
String collectionName = this.template.getCollectionName(DefaultIndexOperationsIntegrationTestsSample.class);
|
||||
|
||||
this.collection = this.template.getDb().getCollection(collectionName);
|
||||
this.collection.dropIndexes();
|
||||
|
||||
this.indexOps = new DefaultIndexOperations(template, collectionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1008
|
||||
*/
|
||||
@Test
|
||||
public void getIndexInfoShouldBeAbleToRead2dsphereIndex() {
|
||||
|
||||
collection.createIndex(GEO_SPHERE_2D);
|
||||
|
||||
IndexInfo info = findAndReturnIndexInfo(GEO_SPHERE_2D);
|
||||
assertThat(info.getIndexFields().get(0).isGeo(), is(true));
|
||||
}
|
||||
|
||||
private IndexInfo findAndReturnIndexInfo(DBObject keys) {
|
||||
return findAndReturnIndexInfo(indexOps.getIndexInfo(), keys);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static IndexInfo findAndReturnIndexInfo(Iterable<IndexInfo> candidates, DBObject keys) {
|
||||
return findAndReturnIndexInfo(candidates, DBCollection.genIndexName(keys));
|
||||
}
|
||||
|
||||
private static IndexInfo findAndReturnIndexInfo(Iterable<IndexInfo> candidates, String name) {
|
||||
|
||||
for (IndexInfo info : candidates) {
|
||||
if (ObjectUtils.nullSafeEquals(name, info.getName())) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
throw new AssertionError(String.format("Index with %s was not found", name));
|
||||
}
|
||||
|
||||
static class DefaultIndexOperationsIntegrationTestsSample {}
|
||||
}
|
||||
@@ -45,7 +45,9 @@ import org.hamcrest.Matchers;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
@@ -99,6 +101,8 @@ public class MappingMongoConverterUnitTests {
|
||||
@Mock ApplicationContext context;
|
||||
@Mock DbRefResolver resolver;
|
||||
|
||||
public @Rule ExpectedException exception = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
@@ -1839,6 +1843,29 @@ public class MappingMongoConverterUnitTests {
|
||||
verify(mock, times(1)).initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1034
|
||||
*/
|
||||
@Test
|
||||
public void rejectsBasicDbListToBeConvertedIntoComplexType() {
|
||||
|
||||
BasicDBList inner = new BasicDBList();
|
||||
inner.add("key");
|
||||
inner.add("value");
|
||||
|
||||
BasicDBList outer = new BasicDBList();
|
||||
outer.add(inner);
|
||||
outer.add(inner);
|
||||
|
||||
BasicDBObject source = new BasicDBObject("attributes", outer);
|
||||
|
||||
exception.expect(MappingException.class);
|
||||
exception.expectMessage(Item.class.getName());
|
||||
exception.expectMessage(BasicDBList.class.getName());
|
||||
|
||||
converter.read(Item.class, source);
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
|
||||
@@ -163,8 +163,8 @@ public class MongoPersistentEntityIndexCreatorUnitTests {
|
||||
new MongoPersistentEntityIndexCreator(mappingContext, factory);
|
||||
|
||||
assertThat(keysCaptor.getValue(), equalTo(new BasicDBObjectBuilder().add("company.address.location", "2d").get()));
|
||||
assertThat(optionsCaptor.getValue(), equalTo(new BasicDBObjectBuilder().add("name", "location").add("min", -180)
|
||||
.add("max", 180).add("bits", 26).get()));
|
||||
assertThat(optionsCaptor.getValue(), equalTo(new BasicDBObjectBuilder().add("name", "company.address.location")
|
||||
.add("min", -180).add("max", 180).add("bits", 26).get()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -576,6 +576,60 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
.resolveIndexForEntity(dummy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1025
|
||||
*/
|
||||
@Test
|
||||
public void shouldUsePathIndexAsIndexNameForDocumentsHavingNamedNestedCompoundIndexFixedOnCollection() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithNestedDocumentHavingNamedCompoundIndex.class);
|
||||
assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
|
||||
equalTo("propertyOfTypeHavingNamedCompoundIndex.c_index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1025
|
||||
*/
|
||||
@Test
|
||||
public void shouldUseIndexNameForNestedTypesWithNamedCompoundIndexDefinition() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithNestedTypeHavingNamedCompoundIndex.class);
|
||||
assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
|
||||
equalTo("propertyOfTypeHavingNamedCompoundIndex.c_index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1025
|
||||
*/
|
||||
@Test
|
||||
public void shouldUsePathIndexAsIndexNameForDocumentsHavingNamedNestedIndexFixedOnCollection() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithNestedDocumentHavingNamedIndex.class);
|
||||
assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
|
||||
equalTo("propertyOfTypeHavingNamedIndex.property_index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1025
|
||||
*/
|
||||
@Test
|
||||
public void shouldUseIndexNameForNestedTypesWithNamedIndexDefinition() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithNestedTypeHavingNamedIndex.class);
|
||||
assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"),
|
||||
equalTo("propertyOfTypeHavingNamedIndex.property_index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1025
|
||||
*/
|
||||
@Test
|
||||
public void shouldUseIndexNameOnRootLevel() {
|
||||
|
||||
List<IndexDefinitionHolder> indexDefinitions = prepareMappingContextAndResolveIndexForType(DocumentWithNamedIndex.class);
|
||||
assertThat((String) indexDefinitions.get(0).getIndexOptions().get("name"), equalTo("property_index"));
|
||||
}
|
||||
|
||||
@Document
|
||||
static class MixedIndexRoot {
|
||||
|
||||
@@ -668,6 +722,54 @@ public class MongoPersistentEntityIndexResolverUnitTests {
|
||||
List<SelfCyclingViaCollectionType> cyclic;
|
||||
|
||||
}
|
||||
|
||||
@Document
|
||||
@CompoundIndex(name = "c_index", def = "{ foo:1, bar:1 }")
|
||||
static class DocumentWithNamedCompoundIndex {
|
||||
|
||||
String property;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class DocumentWithNamedIndex {
|
||||
|
||||
@Indexed(name = "property_index") String property;
|
||||
}
|
||||
|
||||
static class TypeWithNamedIndex {
|
||||
|
||||
@Indexed(name = "property_index") String property;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class DocumentWithNestedDocumentHavingNamedCompoundIndex {
|
||||
|
||||
DocumentWithNamedCompoundIndex propertyOfTypeHavingNamedCompoundIndex;
|
||||
}
|
||||
|
||||
@CompoundIndex(name = "c_index", def = "{ foo:1, bar:1 }")
|
||||
static class TypeWithNamedCompoundIndex {
|
||||
String property;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class DocumentWithNestedTypeHavingNamedCompoundIndex {
|
||||
|
||||
TypeWithNamedCompoundIndex propertyOfTypeHavingNamedCompoundIndex;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class DocumentWithNestedDocumentHavingNamedIndex {
|
||||
|
||||
DocumentWithNamedIndex propertyOfTypeHavingNamedIndex;
|
||||
}
|
||||
|
||||
@Document
|
||||
static class DocumentWithNestedTypeHavingNamedIndex {
|
||||
|
||||
TypeWithNamedIndex propertyOfTypeHavingNamedIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<IndexDefinitionHolder> prepareMappingContextAndResolveIndexForType(Class<?> type) {
|
||||
|
||||
@@ -949,4 +949,18 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
public void shouldFindPersonsWhenUsingQueryDslPerdicatedOnIdProperty() {
|
||||
assertThat(repository.findAll(person.id.in(Arrays.asList(dave.id, carter.id))), containsInAnyOrder(dave, carter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1030
|
||||
*/
|
||||
@Test
|
||||
public void executesSingleEntityQueryWithProjectionCorrectly() {
|
||||
|
||||
PersonSummary result = repository.findSummaryByLastname("Beauford");
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.firstname, is("Carter"));
|
||||
assertThat(result.lastname, is("Beauford"));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,4 +302,9 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
*/
|
||||
@Query("{lastname:?0, address.street:{$in:?1}}")
|
||||
Page<Person> findByCustomQueryLastnameAndAddressStreetInList(String lastname, List<String> streetNames, Pageable page);
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1030
|
||||
*/
|
||||
PersonSummary findSummaryByLastname(String lastname);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PersonSummary {
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class CleanMongoDB implements TestRule {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CleanMongoDB.class);
|
||||
|
||||
public enum Types {
|
||||
DATABASE, COLLECTION, INDEX;
|
||||
}
|
||||
|
||||
private Set<String> preserveDatabases = new HashSet<String>() {
|
||||
|
||||
private static final long serialVersionUID = -8698807376808700046L;
|
||||
|
||||
{
|
||||
add("admin");
|
||||
add("local");
|
||||
}
|
||||
};
|
||||
|
||||
private Set<String> dbNames = new HashSet<String>();
|
||||
private Set<String> collectionNames = new HashSet<String>();
|
||||
private Set<Types> types = new HashSet<CleanMongoDB.Types>();
|
||||
private MongoClient client;
|
||||
|
||||
public CleanMongoDB() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CleanMongoDB(String host, int port) throws UnknownHostException {
|
||||
this(new MongoClient(host, port));
|
||||
}
|
||||
|
||||
public CleanMongoDB(MongoClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public static CleanMongoDB everything() {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.DATABASE);
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public static CleanMongoDB databases(String... dbNames) {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.DATABASE);
|
||||
cleanMongoDB.collectionNames.addAll(Arrays.asList(dbNames));
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public static CleanMongoDB indexes() {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.INDEX);
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public CleanMongoDB clean(Types... types) {
|
||||
|
||||
this.types.addAll(Arrays.asList(types));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Statement apply() {
|
||||
return apply(null, null);
|
||||
}
|
||||
|
||||
public Statement apply(Statement base, Description description) {
|
||||
return new MongoCleanStatement(base);
|
||||
}
|
||||
|
||||
private class MongoCleanStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
public MongoCleanStatement(Statement base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
|
||||
if (base != null) {
|
||||
base.evaluate();
|
||||
}
|
||||
|
||||
boolean isInternal = false;
|
||||
if (client == null) {
|
||||
client = new MongoClient();
|
||||
isInternal = true;
|
||||
}
|
||||
|
||||
Collection<String> dbNamesToUse = dbNames;
|
||||
if (dbNamesToUse.isEmpty()) {
|
||||
dbNamesToUse = client.getDatabaseNames();
|
||||
}
|
||||
|
||||
for (String dbName : dbNamesToUse) {
|
||||
|
||||
if (preserveDatabases.contains(dbName.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (types.contains(Types.DATABASE)) {
|
||||
client.dropDatabase(dbName);
|
||||
LOGGER.debug("Dropping DB '{}'. ", dbName);
|
||||
}
|
||||
|
||||
if (types.contains(Types.COLLECTION)) {
|
||||
|
||||
DB db = client.getDB(dbName);
|
||||
Collection<String> collectionsToUse = initCollectionNames(db);
|
||||
for (String collectionName : collectionsToUse) {
|
||||
if (db.collectionExists(collectionName)) {
|
||||
db.getCollectionFromString(collectionName).drop();
|
||||
LOGGER.debug("Dropping collection '{}' for DB '{}'. ", collectionName, dbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (types.contains(Types.INDEX)) {
|
||||
|
||||
DB db = client.getDB(dbName);
|
||||
Collection<String> collectionsToUse = initCollectionNames(db);
|
||||
for (String collectionName : collectionsToUse) {
|
||||
if (db.collectionExists(collectionName)) {
|
||||
db.getCollectionFromString(collectionName).dropIndexes();
|
||||
LOGGER.debug("Dropping indexes in collection '{}' for DB '{}'. ", collectionName, dbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInternal) {
|
||||
client.close();
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> initCollectionNames(DB db) {
|
||||
|
||||
Collection<String> collectionsToUse = collectionNames;
|
||||
if (CollectionUtils.isEmpty(collectionsToUse)) {
|
||||
collectionsToUse = db.getCollectionNames();
|
||||
}
|
||||
return collectionsToUse;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import org.junit.runner.Result;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
import org.springframework.data.mongodb.test.util.CleanMongoDB.Types;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class CleanMongoDBJunitRunListener extends RunListener {
|
||||
|
||||
@Override
|
||||
public void testRunFinished(Result result) throws Exception {
|
||||
super.testRunFinished(result);
|
||||
try {
|
||||
new CleanMongoDB().clean(Types.INDEX).apply().evaluate();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.test.util.CleanMongoDB.Types;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CleanMongoDBTests {
|
||||
|
||||
private CleanMongoDB cleaner;
|
||||
private @Mock Statement baseStatementMock;
|
||||
private @Mock Description descriptionMock;
|
||||
private @Mock MongoClient mongoClientMock;
|
||||
private @Mock DB db1mock;
|
||||
private @Mock DB db2mock;
|
||||
private @Mock DBCollection collection1mock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
when(mongoClientMock.getDatabaseNames()).thenReturn(Arrays.asList("admin", "db1", "db2"));
|
||||
when(mongoClientMock.getDB(eq("db1"))).thenReturn(db1mock);
|
||||
when(mongoClientMock.getDB(eq("db2"))).thenReturn(db2mock);
|
||||
when(db1mock.collectionExists(anyString())).thenReturn(true);
|
||||
when(db2mock.collectionExists(anyString())).thenReturn(true);
|
||||
when(db1mock.getCollectionNames()).thenReturn(Collections.singleton("collection-1"));
|
||||
when(db2mock.getCollectionNames()).thenReturn(Collections.<String> emptySet());
|
||||
when(db1mock.getCollectionFromString(eq("collection-1"))).thenReturn(collection1mock);
|
||||
|
||||
cleaner = new CleanMongoDB(mongoClientMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preservesSystemCollectionsCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.DATABASE);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, times(1)).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, times(1)).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removesCollectionsCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.COLLECTION);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
|
||||
verify(collection1mock, times(1)).drop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removesIndexesCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.INDEX);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
|
||||
verify(collection1mock, times(1)).dropIndexes();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,47 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 1.5.4.RELEASE (2014-08-27)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-1038 - Assert Mongo instances cleand up properly after test runs.
|
||||
* DATAMONGO-1034 - Improve error message when trying to convert incompatible types.
|
||||
* DATAMONGO-1033 - Release 1.5.4.
|
||||
* DATAMONGO-1030 - Query methods retuning a single entity does not work with projecting types.
|
||||
* DATAMONGO-1027 - Collection inherits complex index from embedded class/object.
|
||||
* DATAMONGO-1025 - Duplicate index creation on embedded documents.
|
||||
* DATAMONGO-1020 - LimitOperator should be a public class.
|
||||
* DATAMONGO-1008 - IndexOperations fail, when "2dsphere" index is present.
|
||||
|
||||
|
||||
Changes in version 1.6.0.RC1 (2014-08-13)
|
||||
-----------------------------------------
|
||||
* DATAMONGO-1024 - Upgrade to Java driver 2.12.3.
|
||||
* DATAMONGO-1021 - Release 1.6 RC1.
|
||||
* DATAMONGO-1020 - LimitOperator should be a public class.
|
||||
* DATAMONGO-1019 - Correct examples in reference documentation.
|
||||
* DATAMONGO-1017 - Add support for custom implementations in CDI repositories.
|
||||
* DATAMONGO-1016 - Remove deprecations in geospatial area.
|
||||
* DATAMONGO-1015 - Move to Asciidoctor for reference documentation.
|
||||
* DATAMONGO-1012 - Proxies for lazy DBRefs with field access should have their id values resolved eagerly.
|
||||
* DATAMONGO-1009 - Adapt to new multi-store configuration detection.
|
||||
* DATAMONGO-1008 - IndexOperations fail, when "2dsphere" index is present.
|
||||
* DATAMONGO-1005 - Improve cycle-detection for DbRef's.
|
||||
* DATAMONGO-1002 - Update.toString(…) might throw exception.
|
||||
* DATAMONGO-1001 - Can't save/update lazy load object.
|
||||
* DATAMONGO-999 - Multiple Mongo Instances always have the same MongoOption Reference - MongoOptionsFactoryBean has a static instance of MongoOptions.
|
||||
* DATAMONGO-996 - Pagination broken after introduction of the support for top/first.
|
||||
* DATAMONGO-995 - Parameter binding in String-based query does not bind all parameters.
|
||||
* DATAMONGO-993 - The system variables $$CURRENT and $$ROOT not handled correctly.
|
||||
* DATAMONGO-992 - Entity can't be deserialized if @TypeAlias is used.
|
||||
* DATAMONGO-991 - Adapt to deprecation removals in Spring Data Commons.
|
||||
* DATAMONGO-989 - MatchOperation should accept CriteriaDefinition.
|
||||
* DATAMONGO-987 - Problem with lazy loading in @DBRef when getting data using MongoTemplate.
|
||||
* DATAMONGO-974 - synthetic field target's name is returned instead of the alias name.
|
||||
* DATAMONGO-973 - Add support for deriving full text queries.
|
||||
* DATAMONGO-957 - Add support for query modifiers.
|
||||
* DATAMONGO-420 - Extra quotes being added to @Query values and fields.
|
||||
|
||||
|
||||
Changes in version 1.5.2.RELEASE (2014-07-28)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-1007 - Release 1.5.2.
|
||||
@@ -444,7 +485,7 @@ Changes in version 1.2.2.GA (2013-07-19)
|
||||
Changes in version 1.3.0.M1 (2013-06-04)
|
||||
----------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-571] - Spring Data for MongoDb doesn't save null values when @Version is added to domain class
|
||||
* [DATAMONGO-571] - Spring Data for MongoDb doesn't save null values when @Version is added to domain class
|
||||
* [DATAMONGO-612] - Fix PDF reference documentation name
|
||||
* [DATAMONGO-613] - Images missing from reference documentation
|
||||
* [DATAMONGO-617] - NullPointerException in MongoTemplate.initializeVersionProperty(…)
|
||||
@@ -480,7 +521,7 @@ Changes in version 1.3.0.M1 (2013-06-04)
|
||||
* [DATAMONGO-637] - Typo in Query.query(…)
|
||||
* [DATAMONGO-651] - WriteResult not available from thrown Exception
|
||||
* [DATAMONGO-652] - Add support for elemMatch and positional operator projections
|
||||
* [DATAMONGO-656] - Potential NullPointerException when debugging in MongoTemplate
|
||||
* [DATAMONGO-656] - Potential NullPointerException when debugging in MongoTemplate
|
||||
* [DATAMONGO-657] - Allow to write Map value as DBRef
|
||||
* [DATAMONGO-666] - Fix architecture inconsistency created by MongoDataIntegrityViolationException
|
||||
* [DATAMONGO-680] - SimpleMongoRepository.exists(ID) improvement
|
||||
@@ -502,7 +543,7 @@ Changes in version 1.3.0.M1 (2013-06-04)
|
||||
Changes in version 1.2.1.GA (2013-04-17)
|
||||
----------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-571] - Spring Data for MongoDb doesn't save null values when @Version is added to domain class
|
||||
* [DATAMONGO-571] - Spring Data for MongoDb doesn't save null values when @Version is added to domain class
|
||||
* [DATAMONGO-612] - Fix PDF reference documentation name
|
||||
* [DATAMONGO-613] - Images missing from reference documentation
|
||||
* [DATAMONGO-617] - NullPointerException in MongoTemplate.initializeVersionProperty(…)
|
||||
@@ -599,7 +640,7 @@ Changes in version 1.1.1.GA (2012-10-17)
|
||||
Changes in version 1.1.0.GA (2012-10-10)
|
||||
----------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-523] - @TypeAlias annotation not used with AbstractMongoConfiguration
|
||||
* [DATAMONGO-523] - @TypeAlias annotation not used with AbstractMongoConfiguration
|
||||
* [DATAMONGO-527] - Criteria.equals(…) broken for complex criterias
|
||||
* [DATAMONGO-530] - MongoMappingContext.setApplicationContext(…) does not invoke superclass method
|
||||
* [DATAMONGO-531] - StackOverflowError when persisting Groovy beans
|
||||
@@ -676,16 +717,16 @@ Changes in version 1.1.0.M2 (2012-24-07)
|
||||
* [DATAMONGO-446] - Pageable query methods returning List are broken
|
||||
* [DATAMONGO-447] - Removal of Documents fails in in debug mode for Documents with complex ids
|
||||
* [DATAMONGO-450] - enabling DEBUG causes RuntimeException
|
||||
* [DATAMONGO-454] - ServerAddressPropertyEditor fails if a hostname is unresolvable
|
||||
* [DATAMONGO-454] - ServerAddressPropertyEditor fails if a hostname is unresolvable
|
||||
* [DATAMONGO-458] - When reading back empty collections unmodifiable instances of Collections.emptyList/Set is returned.
|
||||
* [DATAMONGO-462] - findAll() fails with NPE - discovering the root cause
|
||||
* [DATAMONGO-465] - Mongo inserts document with "_id" as an integer but saves with "_id" as a string.
|
||||
* [DATAMONGO-465] - Mongo inserts document with "_id" as an integer but saves with "_id" as a string.
|
||||
* [DATAMONGO-467] - String @id field is not mapped to ObjectId when using QueryDSL ".id" path
|
||||
* [DATAMONGO-469] - Query creation from method names using AND criteria does not work anymore
|
||||
* [DATAMONGO-474] - Wrong property is used for Id mapping
|
||||
* [DATAMONGO-475] - 'group' operation fails where query references non primitive property
|
||||
* [DATAMONGO-480] - The WriteResultChecking is not used in case of insert or save of documents.
|
||||
* [DATAMONGO-483] - @Indexed(unique=true, name="foo") puts name's value to the 'key' in the MongoDB
|
||||
* [DATAMONGO-483] - @Indexed(unique=true, name="foo") puts name's value to the 'key' in the MongoDB
|
||||
* [DATAMONGO-489] - ClassCastException when loading Map<String, String[]>
|
||||
|
||||
** Improvement
|
||||
@@ -695,7 +736,7 @@ Changes in version 1.1.0.M2 (2012-24-07)
|
||||
* [DATAMONGO-466] - QueryMapper shouldn't map id properties of nested classes
|
||||
* [DATAMONGO-470] - Criteria and Query should have proper equals(…) and hashCode() method.
|
||||
* [DATAMONGO-477] - Change upper bound of Google Guava package import to 13
|
||||
* [DATAMONGO-482] - typo in documentation - 2 i's in usiing
|
||||
* [DATAMONGO-482] - typo in documentation - 2 i's in usiing
|
||||
* [DATAMONGO-486] - Polish namspace implementation
|
||||
* [DATAMONGO-491] - Release 1.1.0.M2
|
||||
|
||||
@@ -715,13 +756,13 @@ Changes in version 1.0.3.RELEASE (2012-24-07)
|
||||
* [DATAMONGO-474] - Wrong property is used for Id mapping
|
||||
* [DATAMONGO-475] - 'group' operation fails where query references non primitive property
|
||||
* [DATAMONGO-480] - The WriteResultChecking is not used in case of insert or save of documents.
|
||||
* [DATAMONGO-483] - @Indexed(unique=true, name="foo") puts name's value to the 'key' in the MongoDB
|
||||
* [DATAMONGO-483] - @Indexed(unique=true, name="foo") puts name's value to the 'key' in the MongoDB
|
||||
* [DATAMONGO-489] - ClassCastException when loading Map<String, String[]>
|
||||
|
||||
** Improvement
|
||||
* [DATAMONGO-466] - QueryMapper shouldn't map id properties of nested classes
|
||||
* [DATAMONGO-470] - Criteria and Query should have proper equals(…) and hashCode() method.
|
||||
* [DATAMONGO-482] - typo in documentation - 2 i's in usiing
|
||||
* [DATAMONGO-482] - typo in documentation - 2 i's in usiing
|
||||
|
||||
** Task
|
||||
* [DATAMONGO-492] - Release 1.0.3
|
||||
@@ -745,7 +786,7 @@ Changes in version 1.0.2.RELEASE (2012-06-20)
|
||||
* [DATAMONGO-446] - Pageable query methods returning List are broken
|
||||
* [DATAMONGO-447] - Removal of Documents fails in in debug mode for Documents with complex ids
|
||||
* [DATAMONGO-450] - enabling DEBUG causes RuntimeException
|
||||
* [DATAMONGO-454] - ServerAddressPropertyEditor fails if a hostname is unresolvable
|
||||
* [DATAMONGO-454] - ServerAddressPropertyEditor fails if a hostname is unresolvable
|
||||
* [DATAMONGO-461] - MappedConstructor potentially throws NullPointerException
|
||||
* [DATAMONGO-462] - findAll() fails with NPE - discovering the root cause
|
||||
|
||||
@@ -926,7 +967,7 @@ Changes in version 1.0.0.M5 MongoDB (2011-10-24)
|
||||
* [DATAMONGO-282] - Cannot create a "range" query
|
||||
* [DATAMONGO-284] - Execution of Querydsl query maps id incorrectly
|
||||
* [DATAMONGO-285] - NPE in MappingMongoConverter.writeMapInternal when saving a Map<String,Object> with val instance of Collection
|
||||
* [DATAMONGO-288] - querying same property multiple times produces incorrect query
|
||||
* [DATAMONGO-288] - querying same property multiple times produces incorrect query
|
||||
* [DATAMONGO-289] - AbstractMongoEventListener will never call onAfterLoad
|
||||
* [DATAMONGO-294] - List elements nested in Map lose their type when persisted
|
||||
|
||||
@@ -955,7 +996,7 @@ Changes in version 1.0.0.M5 MongoDB (2011-10-24)
|
||||
* [DATAMONGO-274] - Split up repository package according to the structure in Spring Data JPA
|
||||
|
||||
** Task
|
||||
* [DATAMONGO-264] - Ensure Data Document examples work
|
||||
* [DATAMONGO-264] - Ensure Data Document examples work
|
||||
* [DATAMONGO-265] - Create new github repository for mongodb
|
||||
* [DATAMONGO-266] - Create new github repository for CouchDB
|
||||
* [DATAMONGO-297] - Prune project directory
|
||||
@@ -988,7 +1029,7 @@ Changes in version 1.0.0.M4 MongoDB (2011-09-01)
|
||||
* [DATADOC-228] - NullPointerException when persiting Map with null values
|
||||
* [DATADOC-229] - When a parameterized List is used in the PersistentConstructor, conversion fail
|
||||
* [DATADOC-231] - spring-data-mongodb does not work in an OSGi server because of unresolved dependencies
|
||||
* [DATADOC-232] - mongodb allow to $inc many fields in one query, but Updat().inc(firs).inc(last) do only last inc
|
||||
* [DATADOC-232] - mongodb allow to $inc many fields in one query, but Updat().inc(firs).inc(last) do only last inc
|
||||
* [DATADOC-235] - Unable to map unstructured data
|
||||
* [DATADOC-236] - Repository queries do not honour order defined in method name
|
||||
* [DATADOC-237] - @Indexed annotation doesn't honor field name from @Field annotation
|
||||
@@ -1002,7 +1043,7 @@ Changes in version 1.0.0.M4 MongoDB (2011-09-01)
|
||||
|
||||
** Improvement
|
||||
* [DATADOC-32] - SimpleMongoConverter could support identifying Spring EL expressions in keys
|
||||
* [DATADOC-63] - Converters to support use of a 'typeId' strategy to determine class to marshall/unmarshal from Mongo
|
||||
* [DATADOC-63] - Converters to support use of a 'typeId' strategy to determine class to marshall/unmarshal from Mongo
|
||||
* [DATADOC-166] - Check for null if various template CRUD methods
|
||||
* [DATADOC-169] - Registering custom converters for a type requires treating the type as simple in mapping context
|
||||
* [DATADOC-171] - IllegalArgumentException when persisting entity with BigDecimal field
|
||||
@@ -1085,7 +1126,7 @@ Querying / Updating
|
||||
* [DATADOC-146] - Advanced Regexp Queries
|
||||
|
||||
Mapping
|
||||
* [DATADOC-95] - Can not save an object that has not had any of its properties set
|
||||
* [DATADOC-95] - Can not save an object that has not had any of its properties set
|
||||
* [DATADOC-97] - ID replacement not working correctly when using updateFirst/updateMulti
|
||||
* [DATADOC-98] - Collection<Collection> or Object[][] doesn't save correctly
|
||||
* [DATADOC-109] - Add MappingContext to MongoConverter interface
|
||||
@@ -1136,10 +1177,10 @@ Mapping
|
||||
* [DATADOC-33] - Introduce annotation to demarcate id field in a domain object
|
||||
|
||||
Repository
|
||||
* [DATADOC-47, DATACMNS-17] - Adapted new metamodel API
|
||||
* [DATADOC-47, DATACMNS-17] - Adapted new metamodel API
|
||||
* [DATADOC-46] - Added support for 'In' and 'NotIn' keyword
|
||||
* [DATADOC-49] - Fixed 'And' and 'Or' keywords
|
||||
* [DATADOC-41] - Added support for executing QueryDsl predicates
|
||||
* [DATADOC-41] - Added support for executing QueryDsl predicates
|
||||
* [DATADOC-69] - Let repository namespace pickup the default mapping context bean and allow configuration
|
||||
* [DATADOC-24] - Allow use of @Query annotation to define queries
|
||||
* [DATADOC-34] - Create indexes for columns that are mentioned in query methods
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 1.5.2
|
||||
Spring Data MongoDB 1.5.4
|
||||
Copyright (c) [2010-2014] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
|
||||
Reference in New Issue
Block a user