Compare commits
15 Commits
1.3.0.RC1
...
1.3.1.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b17ec47003 | ||
|
|
8c7b558d39 | ||
|
|
a3faabf718 | ||
|
|
1a46abfbb9 | ||
|
|
61284228dd | ||
|
|
8cb92de1ee | ||
|
|
5d3cc3fa04 | ||
|
|
c0b99740dc | ||
|
|
595bbd3aa7 | ||
|
|
5d2fc31164 | ||
|
|
a9dc0fae69 | ||
|
|
0605c7b753 | ||
|
|
21352a8829 | ||
|
|
58e1d2dbd9 | ||
|
|
4f7821e3c2 |
@@ -26,7 +26,7 @@ Add the Maven dependency:
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.2.3.RELEASE</version>
|
||||
<version>1.3.1.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -36,7 +36,7 @@ If you'd rather like the latest snapshots of the upcoming major version, use our
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.3.0.BUILD-SNAPSHOT</version>
|
||||
<version>1.4.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<repository>
|
||||
|
||||
10
pom.xml
10
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.RC1</version>
|
||||
<version>1.3.1.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.1.1.RELEASE</version>
|
||||
<version>1.2.0.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.6.0.RC1</springdata.commons>
|
||||
<springdata.commons>1.6.1.RELEASE</springdata.commons>
|
||||
<mongo>2.10.1</mongo>
|
||||
</properties>
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-lib-milestone</id>
|
||||
<url>http://repo.springsource.org/libs-milestone-local</url>
|
||||
<id>spring-lib-release</id>
|
||||
<url>http://repo.springsource.org/libs-release-local</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.RC1</version>
|
||||
<version>1.3.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.3.0.RC1</version>
|
||||
<version>1.3.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.RC1</version>
|
||||
<version>1.3.1.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.3.0.RC1</version>
|
||||
<version>1.3.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.0.RC1</version>
|
||||
<version>1.3.1.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.w3c.dom.Element;
|
||||
* @author Jon Brisbin
|
||||
* @author Oliver Gierke
|
||||
* @author Maciej Walkowiak
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
|
||||
@@ -105,6 +106,11 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
converterBuilder.addConstructorArgReference(dbFactoryRef);
|
||||
converterBuilder.addConstructorArgReference(ctxRef);
|
||||
|
||||
String typeMapperRef = element.getAttribute("type-mapper-ref");
|
||||
if (StringUtils.hasText(typeMapperRef)) {
|
||||
converterBuilder.addPropertyReference("typeMapper", typeMapperRef);
|
||||
}
|
||||
|
||||
if (conversionsDefinition != null) {
|
||||
converterBuilder.addPropertyValue("customConversions", conversionsDefinition);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -26,14 +26,13 @@ import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
|
||||
/**
|
||||
* Helper class featuring helper methods for internal MongoDb classes.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Mainly intended for internal use within the framework.
|
||||
* Helper class featuring helper methods for internal MongoDb classes. Mainly intended for internal use within the
|
||||
* framework.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Graeme Rocher
|
||||
* @author Oliver Gierke
|
||||
* @author Randy Watler
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class MongoDbUtils {
|
||||
@@ -131,8 +130,11 @@ public abstract class MongoDbUtils {
|
||||
holderToUse.addDB(databaseName, db);
|
||||
}
|
||||
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
// synchronize holder only if not yet synchronized
|
||||
if (!holderToUse.isSynchronizedWithTransaction()) {
|
||||
TransactionSynchronizationManager.registerSynchronization(new MongoSynchronization(holderToUse, mongo));
|
||||
holderToUse.setSynchronizedWithTransaction(true);
|
||||
}
|
||||
|
||||
if (holderToUse != dbHolder) {
|
||||
TransactionSynchronizationManager.bindResource(mongo, holderToUse);
|
||||
|
||||
@@ -49,6 +49,7 @@ import com.mongodb.WriteResult;
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Tobias Trelle
|
||||
* @author Chuong Ngo
|
||||
*/
|
||||
public interface MongoOperations {
|
||||
|
||||
@@ -703,6 +704,18 @@ public interface MongoOperations {
|
||||
*/
|
||||
WriteResult upsert(Query query, Update update, String collectionName);
|
||||
|
||||
/**
|
||||
* Performs an upsert. If no document is found that matches the query, a new document is created and inserted by
|
||||
* combining the query document and the update document.
|
||||
*
|
||||
* @param query the query document that specifies the criteria used to select a record to be upserted
|
||||
* @param update the update document that contains the updated object or $ operators to manipulate the existing object
|
||||
* @param entityClass class of the pojo to be operated on
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @return the WriteResult which lets you access the results of the previous write.
|
||||
*/
|
||||
WriteResult upsert(Query query, Update update, Class<?> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the collection of the entity class that matches the query document with
|
||||
* the provided update document.
|
||||
@@ -727,6 +740,19 @@ public interface MongoOperations {
|
||||
*/
|
||||
WriteResult updateFirst(Query query, Update update, String collectionName);
|
||||
|
||||
/**
|
||||
* Updates the first object that is found in the specified collection that matches the query document criteria with
|
||||
* the provided updated document.
|
||||
*
|
||||
* @param query the query document that specifies the criteria used to select a record to be updated
|
||||
* @param update the update document that contains the updated object or $ operators to manipulate the existing
|
||||
* object.
|
||||
* @param entityClass class of the pojo to be operated on
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @return the WriteResult which lets you access the results of the previous write.
|
||||
*/
|
||||
WriteResult updateFirst(Query query, Update update, Class<?> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
@@ -751,6 +777,19 @@ public interface MongoOperations {
|
||||
*/
|
||||
WriteResult updateMulti(Query query, Update update, String collectionName);
|
||||
|
||||
/**
|
||||
* Updates all objects that are found in the collection for the entity class that matches the query document criteria
|
||||
* with the provided updated document.
|
||||
*
|
||||
* @param query the query document that specifies the criteria used to select a record to be updated
|
||||
* @param update the update document that contains the updated object or $ operators to manipulate the existing
|
||||
* object.
|
||||
* @param entityClass class of the pojo to be operated on
|
||||
* @param collectionName name of the collection to update the object in
|
||||
* @return the WriteResult which lets you access the results of the previous write.
|
||||
*/
|
||||
WriteResult updateMulti(final Query query, final Update update, Class<?> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Remove the given object from the collection by id.
|
||||
*
|
||||
|
||||
@@ -123,6 +123,7 @@ import com.mongodb.util.JSONParseException;
|
||||
* @author Tobias Trelle
|
||||
* @author Sebastian Herold
|
||||
* @author Thomas Darimont
|
||||
* @author Chuong Ngo
|
||||
*/
|
||||
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
|
||||
@@ -565,8 +566,26 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
mongoConverter, entityClass), near.getMetric());
|
||||
List<GeoResult<T>> result = new ArrayList<GeoResult<T>>(results.size());
|
||||
|
||||
int index = 0;
|
||||
int elementsToSkip = near.getSkip() != null ? near.getSkip() : 0;
|
||||
|
||||
for (Object element : results) {
|
||||
result.add(callback.doWith((DBObject) element));
|
||||
|
||||
/*
|
||||
* As MongoDB currently (2.4.4) doesn't support the skipping of elements in near queries
|
||||
* we skip the elements ourselves to avoid at least the document 2 object mapping overhead.
|
||||
*
|
||||
* @see https://jira.mongodb.org/browse/SERVER-3925
|
||||
*/
|
||||
if (index >= elementsToSkip) {
|
||||
result.add(callback.doWith((DBObject) element));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (elementsToSkip > 0) {
|
||||
// as we skipped some elements we have to calculate the averageDistance ourselves:
|
||||
return new GeoResults<T>(result, near.getMetric());
|
||||
}
|
||||
|
||||
DBObject stats = (DBObject) commandResult.get("stats");
|
||||
@@ -928,6 +947,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return doUpdate(collectionName, query, update, null, true, false);
|
||||
}
|
||||
|
||||
public WriteResult upsert(Query query, Update update, Class<?> entityClass, String collectionName) {
|
||||
return doUpdate(collectionName, query, update, entityClass, true, false);
|
||||
}
|
||||
|
||||
public WriteResult updateFirst(Query query, Update update, Class<?> entityClass) {
|
||||
return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, false);
|
||||
}
|
||||
@@ -936,6 +959,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return doUpdate(collectionName, query, update, null, false, false);
|
||||
}
|
||||
|
||||
public WriteResult updateFirst(Query query, Update update, Class<?> entityClass, String collectionName) {
|
||||
return doUpdate(collectionName, query, update, entityClass, false, false);
|
||||
}
|
||||
|
||||
public WriteResult updateMulti(Query query, Update update, Class<?> entityClass) {
|
||||
return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, true);
|
||||
}
|
||||
@@ -944,6 +971,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
return doUpdate(collectionName, query, update, null, false, true);
|
||||
}
|
||||
|
||||
public WriteResult updateMulti(final Query query, final Update update, Class<?> entityClass, String collectionName) {
|
||||
return doUpdate(collectionName, query, update, entityClass, false, true);
|
||||
}
|
||||
|
||||
protected WriteResult doUpdate(final String collectionName, final Query query, final Update update,
|
||||
final Class<?> entityClass, final boolean upsert, final boolean multi) {
|
||||
|
||||
|
||||
@@ -242,6 +242,41 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
public String toString() {
|
||||
return String.format("AggregationField: %s, synthetic: %s", field, synthetic);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof ExposedField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ExposedField that = (ExposedField) obj;
|
||||
|
||||
return this.field.equals(that.field) && this.synthetic == that.synthetic;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * field.hashCode();
|
||||
result += 31 * (synthetic ? 0 : 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,5 +317,34 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
public String toString() {
|
||||
return String.format("$%s", getRaw());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof FieldReference)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldReference that = (FieldReference) obj;
|
||||
|
||||
return this.field.equals(that.field);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return field.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public abstract class ExposedFieldsAggregationOperationContext implements Aggreg
|
||||
*/
|
||||
@Override
|
||||
public FieldReference getReference(Field field) {
|
||||
return getReference(field.getName());
|
||||
return getReference(field.getTarget());
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -231,5 +232,40 @@ public class Fields implements Iterable<Field> {
|
||||
public String toString() {
|
||||
return String.format("AggregationField - name: %s, target: %s", name, target);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof AggregationField)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AggregationField that = (AggregationField) obj;
|
||||
|
||||
return this.name.equals(that.name) && ObjectUtils.nullSafeEquals(this.target, that.target);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * name.hashCode();
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(target);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
@Override
|
||||
public FieldReference getReference(Field field) {
|
||||
|
||||
PropertyPath.from(field.getName(), type);
|
||||
PropertyPath.from(field.getTarget(), type);
|
||||
return getReferenceFor(field);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.springframework.data.convert.WritingConverter;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter;
|
||||
@@ -98,6 +99,7 @@ public class CustomConversions {
|
||||
this.converters.add(StringToBigIntegerConverter.INSTANCE);
|
||||
this.converters.add(URLToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToURLConverter.INSTANCE);
|
||||
this.converters.add(DBObjectToStringConverter.INSTANCE);
|
||||
this.converters.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
this.converters.addAll(converters);
|
||||
|
||||
|
||||
@@ -24,8 +24,11 @@ import org.bson.types.ObjectId;
|
||||
import org.springframework.core.convert.ConversionFailedException;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Wrapper class to contain useful converters for the usage with Mongo.
|
||||
*
|
||||
@@ -147,4 +150,15 @@ abstract class MongoConverters {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
public static enum DBObjectToStringConverter implements Converter<DBObject, String> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String convert(DBObject source) {
|
||||
return source == null ? null : source.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class GeoResults<T> implements Iterable<GeoResult<T>> {
|
||||
private static Distance calculateAverageDistance(List<? extends GeoResult<?>> results, Metric metric) {
|
||||
|
||||
if (results.isEmpty()) {
|
||||
return new Distance(0, null);
|
||||
return new Distance(0, metric);
|
||||
}
|
||||
|
||||
double averageDistance = 0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -39,6 +39,10 @@ import com.mongodb.DBObject;
|
||||
/**
|
||||
* Central class for creating queries. It follows a fluent API style so that you can easily chain together multiple
|
||||
* criteria. Static import of the 'Criteria.where' method will improve readability.
|
||||
*
|
||||
* @author Thomas Risberg
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class Criteria implements CriteriaDefinition {
|
||||
|
||||
@@ -396,34 +400,54 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
/**
|
||||
* Creates an 'or' criteria using the $or operator for all of the provided criteria
|
||||
* <p>
|
||||
* Note that mongodb doesn't support an $or operator to be wrapped in a $not operator.
|
||||
* <p>
|
||||
*
|
||||
* @throws IllegalArgumentException if {@link #orOperator(Criteria...)} follows a not() call directly.
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria orOperator(Criteria... criteria) {
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$or").is(bsonList));
|
||||
return this;
|
||||
return registerCriteriaChainElement(new Criteria("$or").is(bsonList));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria
|
||||
* Creates a 'nor' criteria using the $nor operator for all of the provided criteria.
|
||||
* <p>
|
||||
* Note that mongodb doesn't support an $nor operator to be wrapped in a $not operator.
|
||||
* <p>
|
||||
*
|
||||
* @throws IllegalArgumentException if {@link #norOperator(Criteria...)} follows a not() call directly.
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria norOperator(Criteria... criteria) {
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$nor").is(bsonList));
|
||||
return this;
|
||||
return registerCriteriaChainElement(new Criteria("$nor").is(bsonList));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an 'and' criteria using the $and operator for all of the provided criteria
|
||||
* Creates an 'and' criteria using the $and operator for all of the provided criteria.
|
||||
* <p>
|
||||
* Note that mongodb doesn't support an $and operator to be wrapped in a $not operator.
|
||||
* <p>
|
||||
*
|
||||
* @throws IllegalArgumentException if {@link #andOperator(Criteria...)} follows a not() call directly.
|
||||
* @param criteria
|
||||
*/
|
||||
public Criteria andOperator(Criteria... criteria) {
|
||||
BasicDBList bsonList = createCriteriaList(criteria);
|
||||
criteriaChain.add(new Criteria("$and").is(bsonList));
|
||||
return registerCriteriaChainElement(new Criteria("$and").is(bsonList));
|
||||
}
|
||||
|
||||
private Criteria registerCriteriaChainElement(Criteria criteria) {
|
||||
|
||||
if (lastOperatorWasNot()) {
|
||||
throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: "
|
||||
+ criteria.getCriteriaObject());
|
||||
} else {
|
||||
criteriaChain.add(criteria);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -468,6 +492,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBObject queryCriteria = new BasicDBObject();
|
||||
if (isValue != NOT_SET) {
|
||||
queryCriteria.put(this.key, this.isValue);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.query;
|
||||
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.core.geo.CustomMetric;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
@@ -29,6 +30,7 @@ import com.mongodb.DBObject;
|
||||
* Builder class to build near-queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class NearQuery {
|
||||
|
||||
@@ -38,6 +40,7 @@ public class NearQuery {
|
||||
private Metric metric;
|
||||
private boolean spherical;
|
||||
private Integer num;
|
||||
private Integer skip;
|
||||
|
||||
/**
|
||||
* Creates a new {@link NearQuery}.
|
||||
@@ -116,7 +119,7 @@ public class NearQuery {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the number of results to return.
|
||||
* Configures the maximum number of results to return.
|
||||
*
|
||||
* @param num
|
||||
* @return
|
||||
@@ -126,6 +129,29 @@ public class NearQuery {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the number of results to skip.
|
||||
*
|
||||
* @param skip
|
||||
* @return
|
||||
*/
|
||||
public NearQuery skip(int skip) {
|
||||
this.skip = skip;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link Pageable} to use.
|
||||
*
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
public NearQuery with(Pageable pageable) {
|
||||
this.num = pageable.getOffset() + pageable.getPageSize();
|
||||
this.skip = pageable.getOffset();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max distance results shall have from the configured origin. If a {@link Metric} was set before the given
|
||||
* value will be interpreted as being a value in that metric. E.g.
|
||||
@@ -290,9 +316,18 @@ public class NearQuery {
|
||||
*/
|
||||
public NearQuery query(Query query) {
|
||||
this.query = query;
|
||||
this.skip = query.getSkip();
|
||||
this.num = query.getLimit();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of elements to skip.
|
||||
*/
|
||||
public Integer getSkip() {
|
||||
return skip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DBObject} built by the {@link NearQuery}.
|
||||
*
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.util.Assert;
|
||||
* Base class for {@link RepositoryQuery} implementations for Mongo.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
|
||||
@@ -287,6 +288,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
|
||||
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
|
||||
}
|
||||
|
||||
Pageable pageable = accessor.getPageable();
|
||||
if (pageable != null) {
|
||||
nearQuery.with(pageable);
|
||||
}
|
||||
|
||||
MongoEntityMetadata<?> metadata = method.getEntityInformation();
|
||||
return (GeoResults<Object>) operations.geoNear(nearQuery, metadata.getJavaType(), metadata.getCollectionName());
|
||||
}
|
||||
|
||||
@@ -181,10 +181,10 @@ The base package in which to scan for entities annotated with @Document
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
|
||||
<xsd:attribute name="type-mapper-ref" type="typeMapperRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
The reference to a Mongo. Will default to 'mongo'.
|
||||
The reference to a MongoTypeMapper to be used by this MappingMongoConverter.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
@@ -195,13 +195,6 @@ The base package in which to scan for entities annotated with @Document
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="disable-validation" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener">
|
||||
@@ -257,6 +250,17 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="typeMapperRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoTypeMapper"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="mappingContextRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2013 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.
|
||||
@@ -23,8 +23,11 @@ import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -37,6 +40,7 @@ import com.mongodb.Mongo;
|
||||
* Unit tests for {@link AbstractMongoConfiguration}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class AbstractMongoConfigurationUnitTests {
|
||||
|
||||
@@ -113,6 +117,20 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
assertThat(spElContext.getBeanResolver(), is(notNullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-725
|
||||
*/
|
||||
@Test
|
||||
public void shouldBeAbleToConfigureCustomTypeMapperViaJavaConfig() {
|
||||
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SampleMongoConfiguration.class);
|
||||
MongoTypeMapper typeMapper = context.getBean(CustomMongoTypeMapper.class);
|
||||
MappingMongoConverter mmc = context.getBean(MappingMongoConverter.class);
|
||||
|
||||
assertThat(mmc, is(notNullValue()));
|
||||
assertThat(mmc.getTypeMapper(), is(typeMapper));
|
||||
}
|
||||
|
||||
private static void assertScanningDisabled(final String value) throws ClassNotFoundException {
|
||||
|
||||
AbstractMongoConfiguration configuration = new SampleMongoConfiguration() {
|
||||
@@ -138,6 +156,19 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
MappingMongoConverter mmc = super.mappingMongoConverter();
|
||||
mmc.setTypeMapper(typeMapper());
|
||||
return mmc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MongoTypeMapper typeMapper() {
|
||||
return new CustomMongoTypeMapper();
|
||||
}
|
||||
}
|
||||
|
||||
@Document
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2013 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.config;
|
||||
|
||||
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
class CustomMongoTypeMapper extends DefaultMongoTypeMapper {}
|
||||
@@ -31,6 +31,8 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.mongodb.core.convert.CustomConversions;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.Account;
|
||||
import org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy;
|
||||
import org.springframework.data.mongodb.repository.Person;
|
||||
@@ -42,6 +44,7 @@ import com.mongodb.DBObject;
|
||||
* Integration tests for {@link MappingMongoConverterParser}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class MappingMongoConverterParserIntegrationTests {
|
||||
|
||||
@@ -61,6 +64,15 @@ public class MappingMongoConverterParserIntegrationTests {
|
||||
factory.getBean("converter");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasCustomTypeMapper() {
|
||||
|
||||
MappingMongoConverter converter = factory.getBean("converter", MappingMongoConverter.class);
|
||||
MongoTypeMapper customMongoTypeMapper = factory.getBean(CustomMongoTypeMapper.class);
|
||||
|
||||
assertThat(converter.getTypeMapper(), is(customMongoTypeMapper));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scansForConverterAndSetsUpCustomConversionsAccordingly() {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2013 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.
|
||||
@@ -33,6 +33,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||
*
|
||||
* @see DATAMONGO-36
|
||||
* @author Maciej Walkowiak
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class MappingMongoConverterParserValidationIntegrationTests {
|
||||
|
||||
@@ -65,4 +66,11 @@ public class MappingMongoConverterParserValidationIntegrationTests {
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-validation-disabled.xml"));
|
||||
factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validatingEventListenerCreatedWithCustomTypeMapperConfig() {
|
||||
|
||||
reader.loadBeanDefinitions(new ClassPathResource("namespace/converter-custom-typeMapper.xml"));
|
||||
assertThat(factory.getBean(BeanNames.VALIDATING_EVENT_LISTENER), is(not(nullValue())));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2013 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.
|
||||
@@ -20,6 +20,8 @@ import static org.junit.Assert.*;
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -28,7 +30,9 @@ import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.Mongo;
|
||||
@@ -37,12 +41,12 @@ import com.mongodb.Mongo;
|
||||
* Unit tests for {@link MongoDbUtils}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Randy Watler
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MongoDbUtilsUnitTests {
|
||||
|
||||
@Mock
|
||||
Mongo mongo;
|
||||
@Mock Mongo mongo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -81,4 +85,94 @@ public class MongoDbUtilsUnitTests {
|
||||
assertThat(first, is(notNullValue()));
|
||||
assertThat(MongoDbUtils.getDB(mongo, "first"), is(sameInstance(first)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-737
|
||||
*/
|
||||
@Test
|
||||
public void handlesTransactionSynchronizationLifecycle() {
|
||||
|
||||
// ensure transaction synchronization manager has no registered
|
||||
// transaction synchronizations or bound resources at start of test
|
||||
assertThat(TransactionSynchronizationManager.getSynchronizations().isEmpty(), is(true));
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(true));
|
||||
|
||||
// access database for one mongo instance, (registers transaction
|
||||
// synchronization and binds transaction resource)
|
||||
MongoDbUtils.getDB(mongo, "first");
|
||||
|
||||
// ensure transaction synchronization manager has registered
|
||||
// transaction synchronizations and bound resources
|
||||
assertThat(TransactionSynchronizationManager.getSynchronizations().isEmpty(), is(false));
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(false));
|
||||
|
||||
// simulate transaction completion, (unbinds transaction resource)
|
||||
try {
|
||||
simulateTransactionCompletion();
|
||||
} catch (Exception e) {
|
||||
fail("Unexpected exception thrown during transaction completion: " + e);
|
||||
}
|
||||
|
||||
// ensure transaction synchronization manager has no bound resources
|
||||
// at end of test
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-737
|
||||
*/
|
||||
@Test
|
||||
public void handlesTransactionSynchronizationsLifecycle() {
|
||||
|
||||
// ensure transaction synchronization manager has no registered
|
||||
// transaction synchronizations or bound resources at start of test
|
||||
assertThat(TransactionSynchronizationManager.getSynchronizations().isEmpty(), is(true));
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(true));
|
||||
|
||||
// access multiple databases for one mongo instance, (registers
|
||||
// transaction synchronizations and binds transaction resources)
|
||||
MongoDbUtils.getDB(mongo, "first");
|
||||
MongoDbUtils.getDB(mongo, "second");
|
||||
|
||||
// ensure transaction synchronization manager has registered
|
||||
// transaction synchronizations and bound resources
|
||||
assertThat(TransactionSynchronizationManager.getSynchronizations().isEmpty(), is(false));
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(false));
|
||||
|
||||
// simulate transaction completion, (unbinds transaction resources)
|
||||
try {
|
||||
simulateTransactionCompletion();
|
||||
} catch (Exception e) {
|
||||
fail("Unexpected exception thrown during transaction completion: " + e);
|
||||
}
|
||||
|
||||
// ensure transaction synchronization manager has no bound
|
||||
// transaction resources at end of test
|
||||
assertThat(TransactionSynchronizationManager.getResourceMap().isEmpty(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate transaction rollback/commit completion protocol on managed transaction synchronizations which will unbind
|
||||
* managed transaction resources. Does not swallow exceptions for testing purposes.
|
||||
*
|
||||
* @see TransactionSynchronizationUtils#triggerBeforeCompletion()
|
||||
* @see TransactionSynchronizationUtils#triggerAfterCompletion(int)
|
||||
*/
|
||||
private void simulateTransactionCompletion() {
|
||||
|
||||
// triggerBeforeCompletion() implementation without swallowed exceptions
|
||||
List<TransactionSynchronization> synchronizations = TransactionSynchronizationManager.getSynchronizations();
|
||||
for (TransactionSynchronization synchronization : synchronizations) {
|
||||
synchronization.beforeCompletion();
|
||||
}
|
||||
|
||||
// triggerAfterCompletion() implementation without swallowed exceptions
|
||||
List<TransactionSynchronization> remainingSynchronizations = TransactionSynchronizationManager
|
||||
.getSynchronizations();
|
||||
if (remainingSynchronizations != null) {
|
||||
for (TransactionSynchronization remainingSynchronization : remainingSynchronizations) {
|
||||
remainingSynchronization.afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
import static org.springframework.data.mongodb.core.query.Update.*;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
@@ -112,8 +113,8 @@ public class MongoTemplateTests {
|
||||
mappingContext.setInitialEntitySet(new HashSet<Class<?>>(Arrays.asList(PersonWith_idPropertyOfTypeObjectId.class,
|
||||
PersonWith_idPropertyOfTypeString.class, PersonWithIdPropertyOfTypeObjectId.class,
|
||||
PersonWithIdPropertyOfTypeString.class, PersonWithIdPropertyOfTypeInteger.class,
|
||||
PersonWithIdPropertyOfPrimitiveInt.class, PersonWithIdPropertyOfTypeLong.class,
|
||||
PersonWithIdPropertyOfPrimitiveLong.class)));
|
||||
PersonWithIdPropertyOfTypeBigInteger.class, PersonWithIdPropertyOfPrimitiveInt.class,
|
||||
PersonWithIdPropertyOfTypeLong.class, PersonWithIdPropertyOfPrimitiveLong.class)));
|
||||
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
|
||||
mappingContext.initialize();
|
||||
|
||||
@@ -142,6 +143,7 @@ public class MongoTemplateTests {
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeObjectId.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeString.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeInteger.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveInt.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfTypeLong.class);
|
||||
template.dropCollection(PersonWithIdPropertyOfPrimitiveLong.class);
|
||||
@@ -478,6 +480,25 @@ public class MongoTemplateTests {
|
||||
assertThat(p9q.getId(), is(p9.getId()));
|
||||
checkCollectionContents(PersonWithIdPropertyOfTypeInteger.class, 1);
|
||||
|
||||
/*
|
||||
* @see DATAMONGO-602
|
||||
*/
|
||||
// BigInteger id - provided
|
||||
PersonWithIdPropertyOfTypeBigInteger p9bi = new PersonWithIdPropertyOfTypeBigInteger();
|
||||
p9bi.setFirstName("Sven_9bi");
|
||||
p9bi.setAge(22);
|
||||
p9bi.setId(BigInteger.valueOf(12345));
|
||||
// insert
|
||||
mongoTemplate.insert(p9bi);
|
||||
// also try save
|
||||
mongoTemplate.save(p9bi);
|
||||
assertThat(p9bi.getId(), notNullValue());
|
||||
PersonWithIdPropertyOfTypeBigInteger p9qbi = mongoTemplate.findOne(new Query(where("id").in(p9bi.getId())),
|
||||
PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
assertThat(p9qbi, notNullValue());
|
||||
assertThat(p9qbi.getId(), is(p9bi.getId()));
|
||||
checkCollectionContents(PersonWithIdPropertyOfTypeBigInteger.class, 1);
|
||||
|
||||
// int id - provided
|
||||
PersonWithIdPropertyOfPrimitiveInt p10 = new PersonWithIdPropertyOfPrimitiveInt();
|
||||
p10.setFirstName("Sven_10");
|
||||
@@ -702,6 +723,47 @@ public class MongoTemplateTests {
|
||||
assertThat(results3.size(), is(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-602
|
||||
*/
|
||||
@Test
|
||||
public void testUsingAnInQueryWithBigIntegerId() throws Exception {
|
||||
|
||||
template.remove(new Query(), PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
|
||||
PersonWithIdPropertyOfTypeBigInteger p1 = new PersonWithIdPropertyOfTypeBigInteger();
|
||||
p1.setFirstName("Sven");
|
||||
p1.setAge(11);
|
||||
p1.setId(new BigInteger("2666666666666666665069473312490162649510603601"));
|
||||
template.insert(p1);
|
||||
PersonWithIdPropertyOfTypeBigInteger p2 = new PersonWithIdPropertyOfTypeBigInteger();
|
||||
p2.setFirstName("Mary");
|
||||
p2.setAge(21);
|
||||
p2.setId(new BigInteger("2666666666666666665069473312490162649510603602"));
|
||||
template.insert(p2);
|
||||
PersonWithIdPropertyOfTypeBigInteger p3 = new PersonWithIdPropertyOfTypeBigInteger();
|
||||
p3.setFirstName("Ann");
|
||||
p3.setAge(31);
|
||||
p3.setId(new BigInteger("2666666666666666665069473312490162649510603603"));
|
||||
template.insert(p3);
|
||||
PersonWithIdPropertyOfTypeBigInteger p4 = new PersonWithIdPropertyOfTypeBigInteger();
|
||||
p4.setFirstName("John");
|
||||
p4.setAge(41);
|
||||
p4.setId(new BigInteger("2666666666666666665069473312490162649510603604"));
|
||||
template.insert(p4);
|
||||
|
||||
Query q1 = new Query(Criteria.where("age").in(11, 21, 41));
|
||||
List<PersonWithIdPropertyOfTypeBigInteger> results1 = template.find(q1, PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
Query q2 = new Query(Criteria.where("firstName").in("Ann", "Mary"));
|
||||
List<PersonWithIdPropertyOfTypeBigInteger> results2 = template.find(q2, PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
Query q3 = new Query(Criteria.where("id").in(new BigInteger("2666666666666666665069473312490162649510603601"),
|
||||
new BigInteger("2666666666666666665069473312490162649510603604")));
|
||||
List<PersonWithIdPropertyOfTypeBigInteger> results3 = template.find(q3, PersonWithIdPropertyOfTypeBigInteger.class);
|
||||
assertThat(results1.size(), is(3));
|
||||
assertThat(results2.size(), is(2));
|
||||
assertThat(results3.size(), is(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUsingAnInQueryWithPrimitiveIntId() throws Exception {
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2011 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 java.math.BigInteger;
|
||||
|
||||
public class PersonWithIdPropertyOfTypeBigInteger {
|
||||
|
||||
private BigInteger id;
|
||||
|
||||
private String firstName;
|
||||
|
||||
private int age;
|
||||
|
||||
public BigInteger getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(BigInteger id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PersonWithIdPropertyOfTypeInteger [id=" + id + ", firstName=" + firstName + ", age=" + age + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,10 +16,10 @@
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Aggregation}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AggregationUnitTests {
|
||||
|
||||
@@ -59,17 +59,6 @@ public class GroupOperationUnitTests {
|
||||
assertThat(idClause.get("b"), is((Object) "$c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateComplexIdForGroupOperationWithSingleComplexIdField() {
|
||||
|
||||
// Fields fields = fields().and("a", 42);
|
||||
// GroupOperation groupOperation = new GroupOperation(fields());
|
||||
//
|
||||
// assertThat(groupOperation.toDBObject(Aggregation.DEFAULT_CONTEXT), is(notNullValue()));
|
||||
// assertThat(groupOperation.id, is(notNullValue()));
|
||||
// assertThat(groupOperation.id, is((Object) new BasicDBObject("a", 42)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupFactoryMethodWithMultipleFieldsAndSumOperation() {
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2013 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.aggregation;
|
||||
|
||||
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.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mapping.PropertyReferenceException;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TypeBasedAggregationOperationContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TypeBasedAggregationOperationContextUnitTests {
|
||||
|
||||
MongoMappingContext context;
|
||||
MappingMongoConverter converter;
|
||||
QueryMapper mapper;
|
||||
|
||||
@Mock MongoDbFactory dbFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
this.context = new MongoMappingContext();
|
||||
this.converter = new MappingMongoConverter(dbFactory, context);
|
||||
this.mapper = new QueryMapper(converter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findsSimpleReference() {
|
||||
assertThat(getContext(Foo.class).getReference("bar"), is(notNullValue()));
|
||||
}
|
||||
|
||||
@Test(expected = PropertyReferenceException.class)
|
||||
public void rejectsInvalidFieldReference() {
|
||||
getContext(Foo.class).getReference("foo");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-741
|
||||
*/
|
||||
@Test
|
||||
public void returnsReferencesToNestedFieldsCorrectly() {
|
||||
|
||||
AggregationOperationContext context = getContext(Foo.class);
|
||||
|
||||
Field field = Fields.field("bar.name");
|
||||
|
||||
assertThat(context.getReference("bar.name"), is(notNullValue()));
|
||||
assertThat(context.getReference(field), is(notNullValue()));
|
||||
assertThat(context.getReference(field), is(context.getReference("bar.name")));
|
||||
}
|
||||
|
||||
private TypeBasedAggregationOperationContext getContext(Class<?> type) {
|
||||
return new TypeBasedAggregationOperationContext(type, context, mapper);
|
||||
}
|
||||
|
||||
static class Foo {
|
||||
|
||||
Bar bar;
|
||||
}
|
||||
|
||||
static class Bar {
|
||||
|
||||
String name;
|
||||
}
|
||||
}
|
||||
@@ -1415,6 +1415,16 @@ public class MappingMongoConverterUnitTests {
|
||||
assertThat(((Person) value).lastname, is("converter"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-743
|
||||
*/
|
||||
@Test
|
||||
public void readsIntoStringsOutOfTheBox() {
|
||||
|
||||
DBObject dbObject = new BasicDBObject("firstname", "Dave");
|
||||
assertThat(converter.read(String.class, dbObject), is("{ \"firstname\" : \"Dave\"}"));
|
||||
}
|
||||
|
||||
@Document
|
||||
class MapDBRef {
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef Map<String, MapDBRefVal> map;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-2013 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.
|
||||
@@ -24,6 +24,10 @@ import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class CriteriaTests {
|
||||
|
||||
@Test
|
||||
@@ -68,4 +72,50 @@ public class CriteriaTests {
|
||||
assertThat(left, is(not(right)));
|
||||
assertThat(right, is(not(left)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-507
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenTryingToNegateAndOperation() {
|
||||
|
||||
new Criteria() //
|
||||
.not() //
|
||||
.andOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-507
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenTryingToNegateOrOperation() {
|
||||
|
||||
new Criteria() //
|
||||
.not() //
|
||||
.orOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-507
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenTryingToNegateNorOperation() {
|
||||
|
||||
new Criteria() //
|
||||
.not() //
|
||||
.norOperator(Criteria.where("delete").is(true).and("_id").is(42)); //
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-507
|
||||
*/
|
||||
@Test
|
||||
public void shouldNegateFollowingSimpleExpression() {
|
||||
|
||||
Criteria c = Criteria.where("age").not().gt(18).and("status").is("student");
|
||||
DBObject co = c.getCriteriaObject();
|
||||
|
||||
assertThat(co, is(notNullValue()));
|
||||
assertThat(co.toString(), is("{ \"age\" : { \"$not\" : { \"$gt\" : 18}} , \"status\" : \"student\"}"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,18 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.mongodb.core.geo.Distance;
|
||||
import org.springframework.data.mongodb.core.geo.Metric;
|
||||
import org.springframework.data.mongodb.core.geo.Metrics;
|
||||
import org.springframework.data.mongodb.core.geo.Point;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link NearQuery}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class NearQueryUnitTests {
|
||||
|
||||
@@ -75,4 +79,48 @@ public class NearQueryUnitTests {
|
||||
query = query.maxDistance(new Distance(200, Metrics.KILOMETERS));
|
||||
assertThat(query.getMetric(), is((Metric) Metrics.MILES));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void shouldTakeSkipAndLimitSettingsFromGivenPageable() {
|
||||
|
||||
Pageable pageable = new PageRequest(3, 5);
|
||||
NearQuery query = NearQuery.near(new Point(1, 1)).with(pageable);
|
||||
|
||||
assertThat(query.getSkip(), is(pageable.getPageNumber() * pageable.getPageSize()));
|
||||
assertThat((Integer) query.toDBObject().get("num"), is((pageable.getPageNumber() + 1) * pageable.getPageSize()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void shouldTakeSkipAndLimitSettingsFromGivenQuery() {
|
||||
|
||||
int limit = 10;
|
||||
int skip = 5;
|
||||
NearQuery query = NearQuery.near(new Point(1, 1)).query(
|
||||
Query.query(Criteria.where("foo").is("bar")).limit(limit).skip(skip));
|
||||
|
||||
assertThat(query.getSkip(), is(skip));
|
||||
assertThat((Integer) query.toDBObject().get("num"), is(limit));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void shouldTakeSkipAndLimitSettingsFromPageableEvenIfItWasSpecifiedOnQuery() {
|
||||
|
||||
int limit = 10;
|
||||
int skip = 5;
|
||||
Pageable pageable = new PageRequest(3, 5);
|
||||
NearQuery query = NearQuery.near(new Point(1, 1))
|
||||
.query(Query.query(Criteria.where("foo").is("bar")).limit(limit).skip(skip)).with(pageable);
|
||||
|
||||
assertThat(query.getSkip(), is(pageable.getPageNumber() * pageable.getPageSize()));
|
||||
assertThat((Integer) query.toDBObject().get("num"), is((pageable.getPageNumber() + 1) * pageable.getPageSize()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,4 +590,94 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
|
||||
assertThat(result, hasSize(2));
|
||||
assertThat(result, hasItems(dave, oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void executesGeoPageQueryForWithPageRequestForPageInBetween() {
|
||||
|
||||
Point farAway = new Point(-73.9, 40.7);
|
||||
Point here = new Point(-73.99, 40.73);
|
||||
|
||||
dave.setLocation(farAway);
|
||||
oliver.setLocation(here);
|
||||
carter.setLocation(here);
|
||||
boyd.setLocation(here);
|
||||
leroi.setLocation(here);
|
||||
|
||||
repository.save(Arrays.asList(dave, oliver, carter, boyd, leroi));
|
||||
|
||||
GeoPage<Person> results = repository.findByLocationNear(new Point(-73.99, 40.73), new Distance(2000,
|
||||
Metrics.KILOMETERS), new PageRequest(1, 2));
|
||||
|
||||
assertThat(results.getContent().isEmpty(), is(false));
|
||||
assertThat(results.getNumberOfElements(), is(2));
|
||||
assertThat(results.isFirstPage(), is(false));
|
||||
assertThat(results.isLastPage(), is(false));
|
||||
assertThat(results.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
assertThat(results.getAverageDistance().getNormalizedValue(), is(0.0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void executesGeoPageQueryForWithPageRequestForPageAtTheEnd() {
|
||||
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
|
||||
dave.setLocation(point);
|
||||
oliver.setLocation(point);
|
||||
carter.setLocation(point);
|
||||
|
||||
repository.save(Arrays.asList(dave, oliver, carter));
|
||||
|
||||
GeoPage<Person> results = repository.findByLocationNear(new Point(-73.99, 40.73), new Distance(2000,
|
||||
Metrics.KILOMETERS), new PageRequest(1, 2));
|
||||
assertThat(results.getContent().isEmpty(), is(false));
|
||||
assertThat(results.getNumberOfElements(), is(1));
|
||||
assertThat(results.isFirstPage(), is(false));
|
||||
assertThat(results.isLastPage(), is(true));
|
||||
assertThat(results.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void executesGeoPageQueryForWithPageRequestForJustOneElement() {
|
||||
|
||||
Point point = new Point(-73.99171, 40.738868);
|
||||
dave.setLocation(point);
|
||||
repository.save(dave);
|
||||
|
||||
GeoPage<Person> results = repository.findByLocationNear(new Point(-73.99, 40.73), new Distance(2000,
|
||||
Metrics.KILOMETERS), new PageRequest(0, 2));
|
||||
|
||||
assertThat(results.getContent().isEmpty(), is(false));
|
||||
assertThat(results.getNumberOfElements(), is(1));
|
||||
assertThat(results.isFirstPage(), is(true));
|
||||
assertThat(results.isLastPage(), is(true));
|
||||
assertThat(results.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-445
|
||||
*/
|
||||
@Test
|
||||
public void executesGeoPageQueryForWithPageRequestForJustOneElementEmptyPage() {
|
||||
|
||||
dave.setLocation(new Point(-73.99171, 40.738868));
|
||||
repository.save(dave);
|
||||
|
||||
GeoPage<Person> results = repository.findByLocationNear(new Point(-73.99, 40.73), new Distance(2000,
|
||||
Metrics.KILOMETERS), new PageRequest(1, 2));
|
||||
|
||||
assertThat(results.getContent().isEmpty(), is(true));
|
||||
assertThat(results.getNumberOfElements(), is(0));
|
||||
assertThat(results.isFirstPage(), is(false));
|
||||
assertThat(results.isLastPage(), is(true));
|
||||
assertThat(results.getAverageDistance().getMetric(), is((Metric) Metrics.KILOMETERS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<mongo:mapping-converter type-mapper-ref="customMongoTypeMapper"/>
|
||||
|
||||
<bean name="customMongoTypeMapper" class="org.springframework.data.mongodb.config.CustomMongoTypeMapper"/>
|
||||
</beans>
|
||||
@@ -5,12 +5,14 @@
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<mongo:mapping-converter id="converter" db-factory-ref="factory">
|
||||
<mongo:mapping-converter id="converter" db-factory-ref="factory" type-mapper-ref="customMongoTypeMapper">
|
||||
<mongo:custom-converters base-package="org.springframework.data.mongodb.config" />
|
||||
</mongo:mapping-converter>
|
||||
|
||||
<mongo:db-factory id="factory" />
|
||||
|
||||
<mongo:mapping-converter id="abbreviatingConverter" abbreviate-field-names="true" />
|
||||
|
||||
<bean name="customMongoTypeMapper" class="org.springframework.data.mongodb.config.CustomMongoTypeMapper"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -35,8 +35,7 @@
|
||||
<constructor-arg name="mongoConverter" ref="mappingConverter1"/>
|
||||
</bean>
|
||||
|
||||
<mongo:mapping-converter id="mappingConverter2" base-package="org.springframework.data.mongodb.core.mapping"
|
||||
mongo-template-ref="mongoTemplate2">
|
||||
<mongo:mapping-converter id="mappingConverter2" base-package="org.springframework.data.mongodb.core.mapping">
|
||||
<mongo:custom-converters>
|
||||
<mongo:converter>
|
||||
<bean class="org.springframework.data.mongodb.core.PersonReadConverter"/>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<xi:include href="introduction/why-sd-doc.xml"/>
|
||||
<xi:include href="introduction/requirements.xml"/>
|
||||
<xi:include href="introduction/getting-started.xml"/>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.RC1/src/docbkx/repositories.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.RELEASE/src/docbkx/repositories.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repositories.xml" />
|
||||
</xi:include>
|
||||
</part>
|
||||
@@ -76,10 +76,10 @@
|
||||
<part id="appendix">
|
||||
<title>Appendix</title>
|
||||
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.RC1/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.1.RELEASE/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repository-namespace-reference.xml" />
|
||||
</xi:include>
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.0.RC1/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.1.RELEASE/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repository-query-keywords-reference.xml" />
|
||||
</xi:include>
|
||||
</part>
|
||||
|
||||
@@ -542,4 +542,52 @@ Page<Person> page = repository.findAll(person.lastname.contains("a"),
|
||||
MongoDB queries.</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Miscellaneous</title>
|
||||
|
||||
<para/>
|
||||
|
||||
<section>
|
||||
<title>CDI Integration</title>
|
||||
|
||||
<para>Instances of the repository interfaces are usually created by a
|
||||
container, which Spring is the most natural choice when working with
|
||||
Spring Data. As of version 1.3.0 Spring Data MongoDB ships with a custom
|
||||
CDI extension that allows using the repository abstraction in CDI
|
||||
environments. The extension is part of the JAR so all you need to do to
|
||||
activate it is dropping the Spring Data MongoDB JAR into your classpath.
|
||||
You can now set up the infrastructure by implementing a CDI Producer for
|
||||
the <classname>MongoTemplate</classname>:</para>
|
||||
|
||||
<programlisting language="java">class MongoTemplateProducer {
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public MongoOperations createMongoTemplate() throws UnknownHostException, MongoException {
|
||||
|
||||
MongoDbFactory factory = new SimpleMongoDbFactory(new Mongo(), "database");
|
||||
return new MongoTemplate(factory);
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>The Spring Data MongoDB CDI extension will pick up the
|
||||
<classname>MongoTemplate</classname> available as CDI bean and create a
|
||||
proxy for a Spring Data repository whenever an bean of a repository type
|
||||
is requested by the container. Thus obtaining an instance of a Spring
|
||||
Data repository is a matter of declaring an <code>@Inject</code>-ed
|
||||
property:</para>
|
||||
|
||||
<programlisting language="java">class RepositoryClient {
|
||||
|
||||
@Inject
|
||||
PersonRepository repository;
|
||||
|
||||
public void businessMethod() {
|
||||
|
||||
List<Person> people = repository.findAll();
|
||||
}
|
||||
}</programlisting>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -1057,6 +1057,77 @@ mongoTemplate.save(sample);
|
||||
instance of that interface can be configured at the
|
||||
<classname>DefaultMongoTypeMapper</classname> which can be configured
|
||||
in turn on <classname>MappingMongoConverter</classname>.</para>
|
||||
|
||||
<example>
|
||||
<title>Defining a TypeAlias for an Entity</title>
|
||||
|
||||
<programlisting language="java">@TypeAlias("pers")
|
||||
class Person {
|
||||
|
||||
}</programlisting>
|
||||
|
||||
<para>Note that the resulting document will contain
|
||||
<code>"pers"</code> as the value in the <code>_class</code>
|
||||
Field.</para>
|
||||
</example>
|
||||
</simplesect>
|
||||
|
||||
<simplesect>
|
||||
<title>Configuring custom type mapping</title>
|
||||
|
||||
<para>The following example demonstrates how to configure a custom
|
||||
<classname>MongoTypeMapper</classname> in
|
||||
<classname>MappingMongoConverter</classname>.</para>
|
||||
|
||||
<example>
|
||||
<title>Configuring a custom MongoTypeMapper via Spring Java
|
||||
Config</title>
|
||||
|
||||
<programlisting language="java">class CustomMongoTypeMapper extends DefaultMongoTypeMapper {
|
||||
//implement custom type mapping here
|
||||
}</programlisting>
|
||||
|
||||
<programlisting language="java">@Configuration
|
||||
class SampleMongoConfiguration extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "database";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new Mongo();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public MappingMongoConverter mappingMongoConverter() throws Exception {
|
||||
MappingMongoConverter mmc = super.mappingMongoConverter();
|
||||
mmc.setTypeMapper(customTypeMapper());
|
||||
return mmc;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MongoTypeMapper customTypeMapper() {
|
||||
return new CustomMongoTypeMapper();
|
||||
}
|
||||
}</programlisting>
|
||||
|
||||
<para>Note that we are extending the
|
||||
<classname>AbstractMongoConfiguration</classname> class and override
|
||||
the bean definition of the
|
||||
<classname>MappingMongoConverter</classname> where we configure our
|
||||
custom <classname>MongoTypeMapper</classname>. </para>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Configuring a custom MongoTypeMapper via XML</title>
|
||||
|
||||
<programlisting language="xml"><mongo:mapping-converter type-mapper-ref="customMongoTypeMapper"/>
|
||||
|
||||
<bean name="customMongoTypeMapper" class="com.bubu.mongo.CustomMongoTypeMapper"/></programlisting>
|
||||
</example>
|
||||
</simplesect>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 1.3.1.RELEASE (2013-09-09)
|
||||
---------------------------------------------
|
||||
** Task
|
||||
* [DATAMONGO-751] Upgraded to Spring Data Commons 1.6.1.
|
||||
|
||||
Changes in version 1.3.0.RELEASE (2013-09-09)
|
||||
---------------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-540] MongoTemplate upsert and findOne handle id queries differently.
|
||||
* [DATAMONGO-445] GeoNear Query Doesn't Work with Pageable.
|
||||
* [DATAMONGO-507] Criteria not() is not working.
|
||||
* [DATAMONGO-602] Querying with $in operator on the id field of type BigInteger returns zero results.
|
||||
|
||||
** Improvement
|
||||
* [DATAMONGO-725] Improve configurability and documentation of TypeMapper on MappingMongoConverter.
|
||||
* [DATAMONGO-738] Add methods to MongoTemplate and MongoOperations to allow calling class to pass both the entityClass and the collectionName for the update and upsert methods.
|
||||
* [DATAMONGO-737] Extra MongoSynchronizations cause TransactionSynchronizationManager to throw IllegalStateException on transaction complete.
|
||||
* [DATAMONGO-743] Support returning raw json from a query.
|
||||
|
||||
** Task
|
||||
* [DATAMONGO-742] Document CDI integration in reference documentation.
|
||||
|
||||
Changes in version 1.3.0.RC1 (2013-08-05)
|
||||
-----------------------------------------
|
||||
** Bug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Document 1.3 RC1
|
||||
Spring Data Document 1.3.1 RELEASE
|
||||
Copyright (c) [2010-2013] Pivotal Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SPRING DATA MongoDB 1.3.0.RC1
|
||||
SPRING DATA MongoDB 1.3.0.RELEASE
|
||||
-----------------------------
|
||||
|
||||
Spring Data MongoDB is released under the terms of the Apache Software License Version 2.0 (see license.txt).
|
||||
|
||||
Reference in New Issue
Block a user