Compare commits
20 Commits
1.8.1.RELE
...
1.8.2.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
437a48ff4a | ||
|
|
583339641d | ||
|
|
8af4bef772 | ||
|
|
b0336c27a9 | ||
|
|
0b492b6c55 | ||
|
|
b3116a523b | ||
|
|
2ba9e5f403 | ||
|
|
8b1805a145 | ||
|
|
5832055840 | ||
|
|
a13e7b8b24 | ||
|
|
a152aa3ce8 | ||
|
|
ca56ea4aea | ||
|
|
284e2f462d | ||
|
|
257bc891dd | ||
|
|
d26db17bf0 | ||
|
|
d760d9cc11 | ||
|
|
be65970710 | ||
|
|
418a4f8b8c | ||
|
|
fa5f93aad5 | ||
|
|
504e14d4a3 |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.8.1.RELEASE</version>
|
||||
<version>1.8.2.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.7.1.RELEASE</version>
|
||||
<version>1.7.2.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -28,7 +28,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.11.1.RELEASE</springdata.commons>
|
||||
<springdata.commons>1.11.2.RELEASE</springdata.commons>
|
||||
<mongo>2.13.0</mongo>
|
||||
<mongo.osgi>2.13.0</mongo.osgi>
|
||||
</properties>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.8.1.RELEASE</version>
|
||||
<version>1.8.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>1.8.1.RELEASE</version>
|
||||
<version>1.8.2.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-2015 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.
|
||||
@@ -45,7 +45,7 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
private static final String ENTITY_FIELD_NAME = "_entity_field_name";
|
||||
private static final String ENTITY_FIELD_CLASS = "_entity_field_class";
|
||||
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private MongoTemplate mongoTemplate;
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
@@ -88,8 +88,8 @@ public class MongoChangeSetPersister implements ChangeSetPersister<Object> {
|
||||
if (!changeSet.getValues().containsKey(key)) {
|
||||
String className = (String) dbo.get(ENTITY_FIELD_CLASS);
|
||||
if (className == null) {
|
||||
throw new DataIntegrityViolationException("Unble to convert property " + key + ": Invalid metadata, "
|
||||
+ ENTITY_FIELD_CLASS + " not available");
|
||||
throw new DataIntegrityViolationException(
|
||||
"Unble to convert property " + key + ": Invalid metadata, " + ENTITY_FIELD_CLASS + " not available");
|
||||
}
|
||||
Class<?> clazz = ClassUtils.resolveClassName(className, ClassUtils.getDefaultClassLoader());
|
||||
Object value = mongoTemplate.getConverter().read(clazz, dbo);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.8.1.RELEASE</version>
|
||||
<version>1.8.2.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.8.1.RELEASE</version>
|
||||
<version>1.8.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ public class MongoLog4jAppender extends AppenderSkeleton {
|
||||
|
||||
// Copy properties into document
|
||||
Map<Object, Object> props = event.getProperties();
|
||||
if (null != props && props.size() > 0) {
|
||||
if (null != props && !props.isEmpty()) {
|
||||
BasicDBObject propsDbo = new BasicDBObject();
|
||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
||||
propsDbo.put(entry.getKey().toString(), entry.getValue().toString());
|
||||
|
||||
@@ -39,7 +39,7 @@ public class MongoLog4jAppenderIntegrationTests {
|
||||
|
||||
static final String NAME = MongoLog4jAppenderIntegrationTests.class.getName();
|
||||
|
||||
Logger log = Logger.getLogger(NAME);
|
||||
private static final Logger log = Logger.getLogger(NAME);
|
||||
Mongo mongo;
|
||||
DB db;
|
||||
String collection;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.8.1.RELEASE</version>
|
||||
<version>1.8.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -775,11 +775,17 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
protected WriteConcern prepareWriteConcern(MongoAction mongoAction) {
|
||||
|
||||
WriteConcern wc = writeConcernResolver.resolve(mongoAction);
|
||||
return potentiallyForceAcknowledgedWrite(wc);
|
||||
}
|
||||
|
||||
if (MongoClientVersion.isMongo3Driver()
|
||||
&& ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)
|
||||
&& (wc == null || wc.getW() < 1)) {
|
||||
return WriteConcern.ACKNOWLEDGED;
|
||||
private WriteConcern potentiallyForceAcknowledgedWrite(WriteConcern wc) {
|
||||
|
||||
if (ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)
|
||||
&& MongoClientVersion.isMongo3Driver()) {
|
||||
if (wc == null || wc.getWObject() == null
|
||||
|| (wc.getWObject() instanceof Number && ((Number) wc.getWObject()).intValue() < 1)) {
|
||||
return WriteConcern.ACKNOWLEDGED;
|
||||
}
|
||||
}
|
||||
return wc;
|
||||
}
|
||||
@@ -1573,8 +1579,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"Can not use skip or field specification with map reduce operations");
|
||||
}
|
||||
|
||||
if (query.getLimit() > 0) {
|
||||
if (query.getLimit() > 0 && mapReduceOptions.getLimit() == null) {
|
||||
mapReduceCommand.setLimit(query.getLimit());
|
||||
}
|
||||
if (query.getSortObject() != null) {
|
||||
@@ -1582,6 +1587,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
if (mapReduceOptions.getLimit() != null && mapReduceOptions.getLimit().intValue() > 0) {
|
||||
mapReduceCommand.setLimit(mapReduceOptions.getLimit());
|
||||
}
|
||||
|
||||
if (mapReduceOptions.getJavaScriptMode() != null) {
|
||||
mapReduceCommand.setJsMode(true);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ public class Aggregation {
|
||||
protected Aggregation(List<AggregationOperation> aggregationOperations, AggregationOptions options) {
|
||||
|
||||
Assert.notNull(aggregationOperations, "AggregationOperations must not be null!");
|
||||
Assert.isTrue(aggregationOperations.size() > 0, "At least one AggregationOperation has to be provided");
|
||||
Assert.isTrue(!aggregationOperations.isEmpty(), "At least one AggregationOperation has to be provided");
|
||||
Assert.notNull(options, "AggregationOptions must not be null!");
|
||||
|
||||
this.operations = aggregationOperations;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
@@ -56,7 +57,7 @@ public enum AggregationFunctionExpressions {
|
||||
static class FunctionExpression implements AggregationExpression {
|
||||
|
||||
private final String name;
|
||||
private final Object[] values;
|
||||
private final List<Object> values;
|
||||
|
||||
/**
|
||||
* Creates a new {@link FunctionExpression} for the given name and values.
|
||||
@@ -70,7 +71,7 @@ public enum AggregationFunctionExpressions {
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
|
||||
this.name = name;
|
||||
this.values = values;
|
||||
this.values = Arrays.asList(values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -80,10 +81,10 @@ public enum AggregationFunctionExpressions {
|
||||
@Override
|
||||
public DBObject toDbObject(AggregationOperationContext context) {
|
||||
|
||||
List<Object> args = new ArrayList<Object>(values.length);
|
||||
List<Object> args = new ArrayList<Object>(values.size());
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
args.add(unpack(values[i], context));
|
||||
for (Object value : values) {
|
||||
args.add(unpack(value, context));
|
||||
}
|
||||
|
||||
return new BasicDBObject("$" + name, args);
|
||||
|
||||
@@ -75,15 +75,13 @@ public abstract class AbstractMongoConverter implements MongoConverter, Initiali
|
||||
*/
|
||||
private void initializeConverters() {
|
||||
|
||||
if (!conversionService.canConvert(ObjectId.class, String.class)) {
|
||||
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
|
||||
}
|
||||
if (!conversionService.canConvert(String.class, ObjectId.class)) {
|
||||
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
|
||||
}
|
||||
conversionService.addConverter(ObjectIdToStringConverter.INSTANCE);
|
||||
conversionService.addConverter(StringToObjectIdConverter.INSTANCE);
|
||||
|
||||
if (!conversionService.canConvert(ObjectId.class, BigInteger.class)) {
|
||||
conversionService.addConverter(ObjectIdToBigIntegerConverter.INSTANCE);
|
||||
}
|
||||
|
||||
if (!conversionService.canConvert(BigInteger.class, ObjectId.class)) {
|
||||
conversionService.addConverter(BigIntegerToObjectIdConverter.INSTANCE);
|
||||
}
|
||||
|
||||
@@ -75,9 +75,7 @@ class DBObjectAccessor {
|
||||
String part = parts.next();
|
||||
|
||||
if (parts.hasNext()) {
|
||||
BasicDBObject nestedDbObject = new BasicDBObject();
|
||||
dbObject.put(part, nestedDbObject);
|
||||
dbObject = nestedDbObject;
|
||||
dbObject = getOrCreateNestedDbObject(part, dbObject);
|
||||
} else {
|
||||
dbObject.put(part, value);
|
||||
}
|
||||
@@ -116,8 +114,14 @@ class DBObjectAccessor {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given source object as map, i.e. {@link BasicDBObject}s and maps as is or {@literal null} otherwise.
|
||||
*
|
||||
* @param source can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getAsMap(Object source) {
|
||||
private static Map<String, Object> getAsMap(Object source) {
|
||||
|
||||
if (source instanceof BasicDBObject) {
|
||||
return (BasicDBObject) source;
|
||||
@@ -129,4 +133,26 @@ class DBObjectAccessor {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DBObject} which either already exists in the given source under the given key, or creates a new
|
||||
* nested one, registers it with the source and returns it.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param source must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
private static DBObject getOrCreateNestedDbObject(String key, DBObject source) {
|
||||
|
||||
Object existing = source.get(key);
|
||||
|
||||
if (existing instanceof BasicDBObject) {
|
||||
return (BasicDBObject) existing;
|
||||
}
|
||||
|
||||
DBObject nested = new BasicDBObject();
|
||||
source.put(key, nested);
|
||||
|
||||
return nested;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,9 +111,13 @@ abstract class GeoConverters {
|
||||
@Override
|
||||
public Point convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Assert.isTrue(source.keySet().size() == 2, "Source must contain 2 elements");
|
||||
|
||||
return source == null ? null : new Point((Double) source.get("x"), (Double) source.get("y"));
|
||||
return new Point((Double) source.get("x"), (Double) source.get("y"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
accessor.setProperty(idProperty, idValue);
|
||||
}
|
||||
|
||||
final ObjectPath currentPath = path.push(result, entity, idValue);
|
||||
final ObjectPath currentPath = path.push(result, entity,
|
||||
idValue != null ? dbo.get(idProperty.getFieldName()) : null);
|
||||
|
||||
// Set properties not already set in the constructor
|
||||
entity.doWithProperties(new PropertyHandler<MongoPersistentProperty>() {
|
||||
@@ -290,7 +291,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
final MongoPersistentProperty property = association.getInverse();
|
||||
Object value = dbo.get(property.getFieldName());
|
||||
|
||||
if (value == null) {
|
||||
if (value == null || entity.isConstructorArgument(property)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1197,10 +1198,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getCollectionName());
|
||||
|
||||
if (object != null) {
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
return (T) (object != null ? object : read(type, readRef(dbref), path));
|
||||
}
|
||||
|
||||
|
||||
@@ -946,7 +946,7 @@ public class QueryMapper {
|
||||
*/
|
||||
protected String mapPropertyName(MongoPersistentProperty property) {
|
||||
|
||||
String mappedName = PropertyToFieldNameConverter.INSTANCE.convert(property);
|
||||
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
|
||||
boolean inspect = iterator.hasNext();
|
||||
|
||||
while (inspect) {
|
||||
@@ -955,18 +955,18 @@ public class QueryMapper {
|
||||
boolean isPositional = (isPositionalParameter(partial) && (property.isMap() || property.isCollectionLike()));
|
||||
|
||||
if (isPositional) {
|
||||
mappedName += "." + partial;
|
||||
mappedName.append(".").append(partial);
|
||||
}
|
||||
|
||||
inspect = isPositional && iterator.hasNext();
|
||||
}
|
||||
|
||||
return mappedName;
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
private static boolean isPositionalParameter(String partial) {
|
||||
|
||||
if (partial.equals("$")) {
|
||||
if ("$".equals(partial)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.core.index;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
@@ -44,7 +45,7 @@ public class Index implements IndexDefinition {
|
||||
*
|
||||
* @deprecated since 1.7.
|
||||
*/
|
||||
@Deprecated//
|
||||
@Deprecated //
|
||||
DROP
|
||||
}
|
||||
|
||||
@@ -175,11 +176,18 @@ public class Index implements IndexDefinition {
|
||||
return unique();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.index.IndexDefinition#getIndexKeys()
|
||||
*/
|
||||
public DBObject getIndexKeys() {
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : fieldSpec.keySet()) {
|
||||
dbo.put(k, fieldSpec.get(k).equals(Direction.ASC) ? 1 : -1);
|
||||
|
||||
for (Entry<String, Direction> entry : fieldSpec.entrySet()) {
|
||||
dbo.put(entry.getKey(), Direction.ASC.equals(entry.getValue()) ? 1 : -1);
|
||||
}
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ public class MapReduceOptions {
|
||||
|
||||
private Boolean verbose = true;
|
||||
|
||||
private Integer limit;
|
||||
|
||||
private Map<String, Object> extraOptions = new HashMap<String, Object>();
|
||||
|
||||
/**
|
||||
@@ -64,6 +66,8 @@ public class MapReduceOptions {
|
||||
* @return MapReduceOptions so that methods can be chained in a fluent API style
|
||||
*/
|
||||
public MapReduceOptions limit(int limit) {
|
||||
|
||||
this.limit = limit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -247,6 +251,15 @@ public class MapReduceOptions {
|
||||
return this.scopeVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum number of documents for the input into the map function.
|
||||
*
|
||||
* @return {@literal null} if not set.
|
||||
*/
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public DBObject getOptionsObject() {
|
||||
BasicDBObject cmd = new BasicDBObject();
|
||||
|
||||
@@ -264,6 +277,10 @@ public class MapReduceOptions {
|
||||
cmd.put("scope", scopeVariables);
|
||||
}
|
||||
|
||||
if (limit != null) {
|
||||
cmd.put("limit", limit);
|
||||
}
|
||||
|
||||
if (!extraOptions.keySet().isEmpty()) {
|
||||
cmd.putAll(extraOptions);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -17,13 +17,10 @@ package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
public class MapReduceTiming {
|
||||
|
||||
private long mapTime;
|
||||
|
||||
private long emitLoopTime;
|
||||
|
||||
private long totalTime;
|
||||
private long mapTime, emitLoopTime, totalTime;
|
||||
|
||||
public MapReduceTiming(long mapTime, long emitLoopTime, long totalTime) {
|
||||
|
||||
this.mapTime = mapTime;
|
||||
this.emitLoopTime = emitLoopTime;
|
||||
this.totalTime = totalTime;
|
||||
@@ -41,37 +38,52 @@ public class MapReduceTiming {
|
||||
return totalTime;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MapReduceTiming [mapTime=" + mapTime + ", emitLoopTime=" + emitLoopTime + ", totalTime=" + totalTime + "]";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
|
||||
result = prime * result + (int) (emitLoopTime ^ (emitLoopTime >>> 32));
|
||||
result = prime * result + (int) (mapTime ^ (mapTime >>> 32));
|
||||
result = prime * result + (int) (totalTime ^ (totalTime >>> 32));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MapReduceTiming other = (MapReduceTiming) obj;
|
||||
if (emitLoopTime != other.emitLoopTime)
|
||||
return false;
|
||||
if (mapTime != other.mapTime)
|
||||
return false;
|
||||
if (totalTime != other.totalTime)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(obj instanceof MapReduceTiming)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MapReduceTiming that = (MapReduceTiming) obj;
|
||||
|
||||
return this.emitLoopTime == that.emitLoopTime && //
|
||||
this.mapTime == that.mapTime && //
|
||||
this.totalTime == that.totalTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BSON;
|
||||
@@ -118,7 +119,7 @@ public class Criteria implements CriteriaDefinition {
|
||||
}
|
||||
|
||||
private boolean lastOperatorWasNot() {
|
||||
return this.criteria.size() > 0 && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]);
|
||||
return !this.criteria.isEmpty() && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -581,9 +582,10 @@ public class Criteria implements CriteriaDefinition {
|
||||
DBObject dbo = new BasicDBObject();
|
||||
boolean not = false;
|
||||
|
||||
for (String k : this.criteria.keySet()) {
|
||||
for (Entry<String, Object> entry : criteria.entrySet()) {
|
||||
|
||||
Object value = this.criteria.get(k);
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (requiresGeoJsonFormat(value)) {
|
||||
value = new BasicDBObject("$geometry", value);
|
||||
@@ -591,14 +593,14 @@ public class Criteria implements CriteriaDefinition {
|
||||
|
||||
if (not) {
|
||||
DBObject notDbo = new BasicDBObject();
|
||||
notDbo.put(k, value);
|
||||
notDbo.put(key, value);
|
||||
dbo.put("$not", notDbo);
|
||||
not = false;
|
||||
} else {
|
||||
if ("$not".equals(k) && value == null) {
|
||||
if ("$not".equals(key) && value == null) {
|
||||
not = true;
|
||||
} else {
|
||||
dbo.put(k, value);
|
||||
dbo.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2013 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -83,14 +83,10 @@ public class Field {
|
||||
|
||||
public DBObject getFieldsObject() {
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
DBObject dbo = new BasicDBObject(criteria);
|
||||
|
||||
for (String k : criteria.keySet()) {
|
||||
dbo.put(k, criteria.get(k));
|
||||
}
|
||||
|
||||
for (String k : slices.keySet()) {
|
||||
dbo.put(k, new BasicDBObject("$slice", slices.get(k)));
|
||||
for (Entry<String, Object> entry : slices.entrySet()) {
|
||||
dbo.put(entry.getKey(), new BasicDBObject("$slice", entry.getValue()));
|
||||
}
|
||||
|
||||
for (Entry<String, Criteria> entry : elemMatchs.entrySet()) {
|
||||
@@ -134,8 +130,8 @@ public class Field {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean samePositionKey = this.postionKey == null ? that.postionKey == null : this.postionKey
|
||||
.equals(that.postionKey);
|
||||
boolean samePositionKey = this.postionKey == null ? that.postionKey == null
|
||||
: this.postionKey.equals(that.postionKey);
|
||||
boolean samePositionValue = this.positionValue == that.positionValue;
|
||||
|
||||
return samePositionKey && samePositionValue;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -94,9 +94,9 @@ public class Query {
|
||||
if (existing == null) {
|
||||
this.criteria.put(key, criteriaDefinition);
|
||||
} else {
|
||||
throw new InvalidMongoDbApiUsageException("Due to limitations of the com.mongodb.BasicDBObject, "
|
||||
+ "you can't add a second '" + key + "' criteria. " + "Query already contains '"
|
||||
+ existing.getCriteriaObject() + "'.");
|
||||
throw new InvalidMongoDbApiUsageException(
|
||||
"Due to limitations of the com.mongodb.BasicDBObject, " + "you can't add a second '" + key + "' criteria. "
|
||||
+ "Query already contains '" + existing.getCriteriaObject() + "'.");
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -221,10 +221,8 @@ public class Query {
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
|
||||
for (String k : criteria.keySet()) {
|
||||
CriteriaDefinition c = criteria.get(k);
|
||||
DBObject cl = c.getCriteriaObject();
|
||||
dbo.putAll(cl);
|
||||
for (CriteriaDefinition definition : criteria.values()) {
|
||||
dbo.putAll(definition.getCriteriaObject());
|
||||
}
|
||||
|
||||
if (!restrictedTypes.isEmpty()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -254,7 +254,7 @@ public class Update {
|
||||
* @return
|
||||
*/
|
||||
public Update pullAll(String key, Object[] values) {
|
||||
addFieldOperation("$pullAll", key, Arrays.copyOf(values, values.length));
|
||||
addMultiFieldOperation("$pullAll", key, Arrays.copyOf(values, values.length));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -327,17 +327,22 @@ public class Update {
|
||||
}
|
||||
|
||||
public DBObject getUpdateObject() {
|
||||
|
||||
DBObject dbo = new BasicDBObject();
|
||||
for (String k : modifierOps.keySet()) {
|
||||
dbo.put(k, modifierOps.get(k));
|
||||
}
|
||||
return dbo;
|
||||
return new BasicDBObject(modifierOps);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is not called anymore rather override {@link #addMultiFieldOperation(String, String, Object)}.
|
||||
*
|
||||
* @param operator
|
||||
* @param key
|
||||
* @param value
|
||||
* @deprectaed Use {@link #addMultiFieldOperation(String, String, Object)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
protected void addFieldOperation(String operator, String key, Object value) {
|
||||
|
||||
Assert.hasText(key, "Key/Path for update must not be null or blank.");
|
||||
|
||||
modifierOps.put(operator, new BasicDBObject(key, value));
|
||||
this.keysToUpdate.add(key);
|
||||
}
|
||||
@@ -355,8 +360,8 @@ public class Update {
|
||||
if (existingValue instanceof BasicDBObject) {
|
||||
keyValueMap = (BasicDBObject) existingValue;
|
||||
} else {
|
||||
throw new InvalidDataAccessApiUsageException("Modifier Operations should be a LinkedHashMap but was "
|
||||
+ existingValue.getClass());
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"Modifier Operations should be a LinkedHashMap but was " + existingValue.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2015 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.
|
||||
@@ -29,6 +29,7 @@ import com.mongodb.MongoException;
|
||||
* Base class to encapsulate common configuration settings when connecting to a database
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AbstractMonitor {
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.repository.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Point;
|
||||
@@ -34,7 +37,7 @@ import org.springframework.util.ClassUtils;
|
||||
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
|
||||
|
||||
private final MongoQueryMethod method;
|
||||
private final Object[] values;
|
||||
private final List<Object> values;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MongoParametersParameterAccessor}.
|
||||
@@ -43,9 +46,11 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
||||
* @param values must not be {@literal null}.
|
||||
*/
|
||||
public MongoParametersParameterAccessor(MongoQueryMethod method, Object[] values) {
|
||||
|
||||
super(method.getParameters(), values);
|
||||
|
||||
this.method = method;
|
||||
this.values = values;
|
||||
this.values = Arrays.asList(values);
|
||||
}
|
||||
|
||||
public Range<Distance> getDistanceRange() {
|
||||
@@ -131,6 +136,6 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
|
||||
*/
|
||||
@Override
|
||||
public Object[] getValues() {
|
||||
return values;
|
||||
return values.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,7 +382,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
|
||||
if (next instanceof Collection) {
|
||||
return ((Collection<?>) next).toArray();
|
||||
} else if (next.getClass().isArray()) {
|
||||
} else if (next != null && next.getClass().isArray()) {
|
||||
return (Object[]) next;
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
return PUNCTATION_PATTERN.matcher(source).find() ? Pattern.quote(source) : source;
|
||||
}
|
||||
|
||||
if (source.equals("*")) {
|
||||
if ("*".equals(source)) {
|
||||
return ".*";
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
@@ -224,6 +227,15 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
|
||||
return (String) value;
|
||||
}
|
||||
|
||||
if (value instanceof byte[]) {
|
||||
|
||||
String base64representation = DatatypeConverter.printBase64Binary((byte[]) value);
|
||||
if (!binding.isQuoted()) {
|
||||
return "{ '$binary' : '" + base64representation + "', '$type' : " + BSON.B_GENERAL + "}";
|
||||
}
|
||||
return base64representation;
|
||||
}
|
||||
|
||||
return JSON.serialize(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011 by the original author(s).
|
||||
* Copyright 2011-2015 by the original author(s).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
|
||||
import org.springframework.data.repository.core.support.PersistentEntityInformation;
|
||||
@@ -27,12 +28,14 @@ import org.springframework.data.repository.core.support.PersistentEntityInformat
|
||||
* {@link MongoPersistentEntity} if given.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MappingMongoEntityInformation<T, ID extends Serializable> extends PersistentEntityInformation<T, ID>
|
||||
implements MongoEntityInformation<T, ID> {
|
||||
|
||||
private final MongoPersistentEntity<T> entityMetadata;
|
||||
private final String customCollectionName;
|
||||
private final Class<ID> fallbackIdType;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}.
|
||||
@@ -40,7 +43,18 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity) {
|
||||
this(entity, null);
|
||||
this(entity, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity} and fallback
|
||||
* identifier type.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param fallbackIdType can be {@literal null}.
|
||||
*/
|
||||
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, Class<ID> fallbackIdType) {
|
||||
this(entity, (String) null, fallbackIdType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,11 +65,26 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
|
||||
* @param customCollectionName can be {@literal null}.
|
||||
*/
|
||||
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName) {
|
||||
this(entity, customCollectionName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingMongoEntityInformation} for the given {@link MongoPersistentEntity}, collection name
|
||||
* and identifier type.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param customCollectionName can be {@literal null}.
|
||||
* @param idType can be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName,
|
||||
Class<ID> idType) {
|
||||
|
||||
super(entity);
|
||||
|
||||
this.entityMetadata = entity;
|
||||
this.customCollectionName = customCollectionName;
|
||||
this.fallbackIdType = idType != null ? idType : (Class<ID>) ObjectId.class;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -71,4 +100,19 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
|
||||
public String getIdAttribute() {
|
||||
return entityMetadata.getIdProperty().getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.PersistentEntityInformation#getIdType()
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<ID> getIdType() {
|
||||
|
||||
if (this.entityMetadata.hasIdProperty()) {
|
||||
return super.getIdType();
|
||||
}
|
||||
|
||||
return fallbackIdType != null ? fallbackIdType : (Class<ID>) ObjectId.class;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
@@ -88,7 +89,8 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
@Override
|
||||
protected Object getTargetRepository(RepositoryInformation information) {
|
||||
|
||||
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
|
||||
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType(),
|
||||
information);
|
||||
return getTargetRepositoryViaReflection(information, entityInformation, mongoOperations);
|
||||
}
|
||||
|
||||
@@ -105,9 +107,13 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
return getEntityInformation(domainClass, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T, ID extends Serializable> MongoEntityInformation<T, ID> getEntityInformation(Class<T> domainClass,
|
||||
RepositoryInformation information) {
|
||||
|
||||
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
|
||||
|
||||
@@ -116,7 +122,8 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
|
||||
String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
|
||||
}
|
||||
|
||||
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
|
||||
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity,
|
||||
information != null ? (Class<ID>) information.getIdType() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@ContextConfiguration("classpath:infrastructure.xml")
|
||||
public class MongoAdminIntegrationTests {
|
||||
|
||||
private static Log logger = LogFactory.getLog(MongoAdminIntegrationTests.class);
|
||||
private static final Log logger = LogFactory.getLog(MongoAdminIntegrationTests.class);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private DB testAdminDb;
|
||||
|
||||
@@ -3035,7 +3035,7 @@ public class MongoTemplateTests {
|
||||
*/
|
||||
@Test
|
||||
public void takesLimitIntoAccountWhenStreaming() {
|
||||
|
||||
|
||||
Person youngestPerson = new Person("John", 20);
|
||||
Person oldestPerson = new Person("Jane", 42);
|
||||
|
||||
@@ -3049,6 +3049,100 @@ public class MongoTemplateTests {
|
||||
assertThat(stream.hasNext(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1204
|
||||
*/
|
||||
@Test
|
||||
public void resolvesCyclicDBRefCorrectly() {
|
||||
|
||||
SomeMessage message = new SomeMessage();
|
||||
SomeContent content = new SomeContent();
|
||||
|
||||
template.save(message);
|
||||
template.save(content);
|
||||
|
||||
message.dbrefContent = content;
|
||||
content.dbrefMessage = message;
|
||||
|
||||
template.save(message);
|
||||
template.save(content);
|
||||
|
||||
SomeMessage messageLoaded = template.findOne(query(where("id").is(message.id)), SomeMessage.class);
|
||||
SomeContent contentLoaded = template.findOne(query(where("id").is(content.id)), SomeContent.class);
|
||||
|
||||
assertThat(messageLoaded.dbrefContent.id, is(contentLoaded.id));
|
||||
assertThat(contentLoaded.dbrefMessage.id, is(messageLoaded.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1287
|
||||
*/
|
||||
@Test
|
||||
public void shouldReuseAlreadyResolvedLazyLoadedDBRefWhenUsedAsPersistenceConstrcutorArgument() {
|
||||
|
||||
Document docInCtor = new Document();
|
||||
docInCtor.id = "doc-in-ctor";
|
||||
template.save(docInCtor);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor(
|
||||
docInCtor);
|
||||
|
||||
template.save(source);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)),
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor.class);
|
||||
assertThat(loaded.refToDocUsedInCtor, not(instanceOf(LazyLoadingProxy.class)));
|
||||
assertThat(loaded.refToDocNotUsedInCtor, nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1287
|
||||
*/
|
||||
@Test
|
||||
public void shouldNotReuseLazyLoadedDBRefWhenTypeUsedInPersistenceConstrcutorButValueRefersToAnotherProperty() {
|
||||
|
||||
Document docNotUsedInCtor = new Document();
|
||||
docNotUsedInCtor.id = "doc-but-not-used-in-ctor";
|
||||
template.save(docNotUsedInCtor);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor(
|
||||
null);
|
||||
source.refToDocNotUsedInCtor = docNotUsedInCtor;
|
||||
|
||||
template.save(source);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)),
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor.class);
|
||||
assertThat(loaded.refToDocNotUsedInCtor, instanceOf(LazyLoadingProxy.class));
|
||||
assertThat(loaded.refToDocUsedInCtor, nullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1287
|
||||
*/
|
||||
@Test
|
||||
public void shouldRespectParamterValueWhenAttemptingToReuseLazyLoadedDBRefUsedInPersistenceConstrcutor() {
|
||||
|
||||
Document docInCtor = new Document();
|
||||
docInCtor.id = "doc-in-ctor";
|
||||
template.save(docInCtor);
|
||||
|
||||
Document docNotUsedInCtor = new Document();
|
||||
docNotUsedInCtor.id = "doc-but-not-used-in-ctor";
|
||||
template.save(docNotUsedInCtor);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor source = new DocumentWithLazyDBrefUsedInPresistenceConstructor(
|
||||
docInCtor);
|
||||
source.refToDocNotUsedInCtor = docNotUsedInCtor;
|
||||
|
||||
template.save(source);
|
||||
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor loaded = template.findOne(query(where("id").is(source.id)),
|
||||
DocumentWithLazyDBrefUsedInPresistenceConstructor.class);
|
||||
assertThat(loaded.refToDocUsedInCtor, not(instanceOf(LazyLoadingProxy.class)));
|
||||
assertThat(loaded.refToDocNotUsedInCtor, instanceOf(LazyLoadingProxy.class));
|
||||
}
|
||||
|
||||
static class DoucmentWithNamedIdField {
|
||||
|
||||
@Id String someIdKey;
|
||||
@@ -3351,6 +3445,7 @@ public class MongoTemplateTests {
|
||||
String id;
|
||||
String text;
|
||||
String name;
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef SomeMessage dbrefMessage;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
@@ -3375,4 +3470,18 @@ public class MongoTemplateTests {
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef SomeContent dbrefContent;
|
||||
SomeContent normalContent;
|
||||
}
|
||||
|
||||
static class DocumentWithLazyDBrefUsedInPresistenceConstructor {
|
||||
|
||||
@Id String id;
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocUsedInCtor;
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) Document refToDocNotUsedInCtor;
|
||||
|
||||
@PersistenceConstructor
|
||||
public DocumentWithLazyDBrefUsedInPresistenceConstructor(Document refToDocUsedInCtor) {
|
||||
this.refToDocUsedInCtor = refToDocUsedInCtor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -52,6 +52,7 @@ import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
|
||||
import org.springframework.data.mongodb.core.convert.QueryMapper;
|
||||
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCreator;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
|
||||
import org.springframework.data.mongodb.core.query.BasicQuery;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
@@ -66,6 +67,8 @@ import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.MapReduceCommand;
|
||||
import com.mongodb.MapReduceOutput;
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoException;
|
||||
import com.mongodb.ReadPreference;
|
||||
@@ -422,6 +425,112 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
verify(this.db, times(1)).command(Mockito.any(DBObject.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldUseZeroAsDefaultLimit() {
|
||||
|
||||
ArgumentCaptor<MapReduceCommand> captor = ArgumentCaptor.forClass(MapReduceCommand.class);
|
||||
|
||||
MapReduceOutput output = mock(MapReduceOutput.class);
|
||||
when(output.results()).thenReturn(Collections.<DBObject> emptySet());
|
||||
when(collection.mapReduce(Mockito.any(MapReduceCommand.class))).thenReturn(output);
|
||||
|
||||
Query query = new BasicQuery("{'foo':'bar'}");
|
||||
|
||||
template.mapReduce(query, "collection", "function(){}", "function(key,values){}", Wrapper.class);
|
||||
|
||||
verify(collection).mapReduce(captor.capture());
|
||||
|
||||
assertThat(captor.getValue().getLimit(), is(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldPickUpLimitFromQuery() {
|
||||
|
||||
ArgumentCaptor<MapReduceCommand> captor = ArgumentCaptor.forClass(MapReduceCommand.class);
|
||||
|
||||
MapReduceOutput output = mock(MapReduceOutput.class);
|
||||
when(output.results()).thenReturn(Collections.<DBObject> emptySet());
|
||||
when(collection.mapReduce(Mockito.any(MapReduceCommand.class))).thenReturn(output);
|
||||
|
||||
Query query = new BasicQuery("{'foo':'bar'}");
|
||||
query.limit(100);
|
||||
|
||||
template.mapReduce(query, "collection", "function(){}", "function(key,values){}", Wrapper.class);
|
||||
|
||||
verify(collection).mapReduce(captor.capture());
|
||||
|
||||
assertThat(captor.getValue().getLimit(), is(100));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldPickUpLimitFromOptions() {
|
||||
|
||||
ArgumentCaptor<MapReduceCommand> captor = ArgumentCaptor.forClass(MapReduceCommand.class);
|
||||
|
||||
MapReduceOutput output = mock(MapReduceOutput.class);
|
||||
when(output.results()).thenReturn(Collections.<DBObject> emptySet());
|
||||
when(collection.mapReduce(Mockito.any(MapReduceCommand.class))).thenReturn(output);
|
||||
|
||||
Query query = new BasicQuery("{'foo':'bar'}");
|
||||
|
||||
template.mapReduce(query, "collection", "function(){}", "function(key,values){}",
|
||||
new MapReduceOptions().limit(1000), Wrapper.class);
|
||||
|
||||
verify(collection).mapReduce(captor.capture());
|
||||
assertThat(captor.getValue().getLimit(), is(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldPickUpLimitFromOptionsWhenQueryIsNotPresent() {
|
||||
|
||||
ArgumentCaptor<MapReduceCommand> captor = ArgumentCaptor.forClass(MapReduceCommand.class);
|
||||
|
||||
MapReduceOutput output = mock(MapReduceOutput.class);
|
||||
when(output.results()).thenReturn(Collections.<DBObject> emptySet());
|
||||
when(collection.mapReduce(Mockito.any(MapReduceCommand.class))).thenReturn(output);
|
||||
|
||||
template.mapReduce("collection", "function(){}", "function(key,values){}", new MapReduceOptions().limit(1000),
|
||||
Wrapper.class);
|
||||
|
||||
verify(collection).mapReduce(captor.capture());
|
||||
assertThat(captor.getValue().getLimit(), is(1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void mapReduceShouldPickUpLimitFromOptionsEvenWhenQueryDefinesItDifferently() {
|
||||
|
||||
ArgumentCaptor<MapReduceCommand> captor = ArgumentCaptor.forClass(MapReduceCommand.class);
|
||||
|
||||
MapReduceOutput output = mock(MapReduceOutput.class);
|
||||
when(output.results()).thenReturn(Collections.<DBObject> emptySet());
|
||||
when(collection.mapReduce(Mockito.any(MapReduceCommand.class))).thenReturn(output);
|
||||
|
||||
Query query = new BasicQuery("{'foo':'bar'}");
|
||||
query.limit(100);
|
||||
|
||||
template.mapReduce(query, "collection", "function(){}", "function(key,values){}",
|
||||
new MapReduceOptions().limit(1000), Wrapper.class);
|
||||
|
||||
verify(collection).mapReduce(captor.capture());
|
||||
|
||||
assertThat(captor.getValue().getLimit(), is(1000));
|
||||
}
|
||||
|
||||
class AutogenerateableId {
|
||||
|
||||
@Id BigInteger id;
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2015 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.core.Is.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for DATAMONGO-1289.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class NoExplicitIdTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories(considerNestedRepositories = true)
|
||||
static class Config extends AbstractMongoConfiguration {
|
||||
|
||||
@Override
|
||||
protected String getDatabaseName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mongo mongo() throws Exception {
|
||||
return new MongoClient();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired MongoOperations mongoOps;
|
||||
@Autowired TypeWithoutExplicitIdPropertyRepository repo;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mongoOps.dropCollection(TypeWithoutIdProperty.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1289
|
||||
*/
|
||||
@Test
|
||||
public void saveAndRetrieveTypeWithoutIdPorpertyViaTemplate() {
|
||||
|
||||
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
|
||||
noid.someString = "o.O";
|
||||
|
||||
mongoOps.save(noid);
|
||||
|
||||
TypeWithoutIdProperty retrieved = mongoOps.findOne(query(where("someString").is(noid.someString)),
|
||||
TypeWithoutIdProperty.class);
|
||||
|
||||
assertThat(retrieved.someString, is(noid.someString));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1289
|
||||
*/
|
||||
@Test
|
||||
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepository() {
|
||||
|
||||
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
|
||||
noid.someString = "o.O";
|
||||
|
||||
repo.save(noid);
|
||||
|
||||
TypeWithoutIdProperty retrieved = repo.findBySomeString(noid.someString);
|
||||
assertThat(retrieved.someString, is(noid.someString));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1289
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void saveAndRetrieveTypeWithoutIdPorpertyViaRepositoryFindOne() {
|
||||
|
||||
TypeWithoutIdProperty noid = new TypeWithoutIdProperty();
|
||||
noid.someString = "o.O";
|
||||
|
||||
repo.save(noid);
|
||||
|
||||
Map<String, Object> map = mongoOps.findOne(query(where("someString").is(noid.someString)), Map.class,
|
||||
"typeWithoutIdProperty");
|
||||
|
||||
TypeWithoutIdProperty retrieved = repo.findOne(map.get("_id").toString());
|
||||
assertThat(retrieved.someString, is(noid.someString));
|
||||
}
|
||||
|
||||
static class TypeWithoutIdProperty {
|
||||
|
||||
String someString;
|
||||
}
|
||||
|
||||
static interface TypeWithoutExplicitIdPropertyRepository extends MongoRepository<TypeWithoutIdProperty, String> {
|
||||
|
||||
TypeWithoutIdProperty findBySomeString(String someString);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2015 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.convert;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.ObjectIdToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToObjectIdConverter;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.DBRef;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractMongoConverter}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class AbstractMongoConverterUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1324
|
||||
*/
|
||||
@Test
|
||||
public void registersObjectIdConvertersExplicitly() {
|
||||
|
||||
DefaultConversionService conversionService = spy(new DefaultConversionService());
|
||||
|
||||
new SampleMongoConverter(conversionService).afterPropertiesSet();
|
||||
|
||||
verify(conversionService).addConverter(StringToObjectIdConverter.INSTANCE);
|
||||
verify(conversionService).addConverter(ObjectIdToStringConverter.INSTANCE);
|
||||
}
|
||||
|
||||
static class SampleMongoConverter extends AbstractMongoConverter {
|
||||
|
||||
public SampleMongoConverter(GenericConversionService conversionService) {
|
||||
super(conversionService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoTypeMapper getTypeMapper() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R read(Class<R> type, DBObject source) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Object source, DBObject sink) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convertToMongoType(Object obj, TypeInformation<?> typeInformation) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBRef toDBRef(Object object, MongoPersistentProperty referingProperty) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,28 @@ public class DBObjectAccessorUnitTests {
|
||||
new DBObjectAccessor(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1335
|
||||
*/
|
||||
@Test
|
||||
public void writesAllNestingsCorrectly() {
|
||||
|
||||
MongoPersistentEntity<?> entity = context.getPersistentEntity(TypeWithTwoNestings.class);
|
||||
|
||||
BasicDBObject target = new BasicDBObject();
|
||||
|
||||
DBObjectAccessor accessor = new DBObjectAccessor(target);
|
||||
accessor.put(entity.getPersistentProperty("id"), "id");
|
||||
accessor.put(entity.getPersistentProperty("b"), "b");
|
||||
accessor.put(entity.getPersistentProperty("c"), "c");
|
||||
|
||||
DBObject nestedA = DBObjectTestUtils.getAsDBObject(target, "a");
|
||||
|
||||
assertThat(nestedA, is(notNullValue()));
|
||||
assertThat(nestedA.get("b"), is((Object) "b"));
|
||||
assertThat(nestedA.get("c"), is((Object) "c"));
|
||||
}
|
||||
|
||||
static class ProjectingType {
|
||||
|
||||
String name;
|
||||
@@ -91,4 +113,10 @@ public class DBObjectAccessorUnitTests {
|
||||
String c;
|
||||
}
|
||||
|
||||
static class TypeWithTwoNestings {
|
||||
|
||||
String id;
|
||||
@Field("a.b") String b;
|
||||
@Field("a.c") String c;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2402,10 +2402,10 @@ public class MappingMongoConverterUnitTests {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (source.equals("foo-enum-value")) {
|
||||
if ("foo-enum-value".equals(source)) {
|
||||
return FooBarEnum.FOO;
|
||||
}
|
||||
if (source.equals("bar-enum-value")) {
|
||||
if ("bar-enum-value".equals(source)) {
|
||||
return FooBarEnum.BAR;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
* Copyright 2010-2015 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.
|
||||
@@ -15,12 +15,40 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapreduce;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Mark Pollack
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MapReduceOptionsTests {
|
||||
|
||||
@Test
|
||||
public void testFinalize() {
|
||||
new MapReduceOptions().finalizeFunction("code");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void limitShouldBeIncludedCorrectly() {
|
||||
|
||||
MapReduceOptions options = new MapReduceOptions();
|
||||
options.limit(10);
|
||||
|
||||
assertThat(options.getOptionsObject(), isBsonObject().containing("limit", 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1334
|
||||
*/
|
||||
@Test
|
||||
public void limitShouldNotBePresentInDboWhenNotSet() {
|
||||
assertThat(new MapReduceOptions().getOptionsObject(), isBsonObject().notContaining("limit"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,13 +118,13 @@ public class MapReduceTests {
|
||||
|
||||
int size = 0;
|
||||
for (ContentAndVersion cv : results) {
|
||||
if (cv.getId().equals("Resume")) {
|
||||
if ("Resume".equals(cv.getId())) {
|
||||
assertEquals(6, cv.getValue().longValue());
|
||||
}
|
||||
if (cv.getId().equals("Schema")) {
|
||||
if ("Schema".equals(cv.getId())) {
|
||||
assertEquals(2, cv.getValue().longValue());
|
||||
}
|
||||
if (cv.getId().equals("mongoDB How-To")) {
|
||||
if ("mongoDB How-To".equals(cv.getId())) {
|
||||
assertEquals(2, cv.getValue().longValue());
|
||||
}
|
||||
size++;
|
||||
@@ -141,13 +141,13 @@ public class MapReduceTests {
|
||||
new MapReduceOptions().outputCollection("jmr2_out"), NumberAndVersion.class);
|
||||
int size = 0;
|
||||
for (NumberAndVersion nv : results) {
|
||||
if (nv.getId().equals("1")) {
|
||||
if ("1".equals(nv.getId())) {
|
||||
assertEquals(2, nv.getValue().longValue());
|
||||
}
|
||||
if (nv.getId().equals("2")) {
|
||||
if ("2".equals(nv.getId())) {
|
||||
assertEquals(6, nv.getValue().longValue());
|
||||
}
|
||||
if (nv.getId().equals("3")) {
|
||||
if ("3".equals(nv.getId())) {
|
||||
assertEquals(2, nv.getValue().longValue());
|
||||
}
|
||||
size++;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2014 the original author or authors.
|
||||
* Copyright 2010-2015 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,9 +23,11 @@ import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Test cases for {@link Update}.
|
||||
@@ -484,4 +486,22 @@ public class UpdateTests {
|
||||
public void pushShouldThrowExceptionWhenGivenNegativePosition() {
|
||||
new Update().push("foo").atPosition(-1).each("booh");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1346
|
||||
*/
|
||||
@Test
|
||||
public void registersMultiplePullAllClauses() {
|
||||
|
||||
Update update = new Update();
|
||||
update.pullAll("field1", new String[] { "foo" });
|
||||
update.pullAll("field2", new String[] { "bar" });
|
||||
|
||||
DBObject updateObject = update.getUpdateObject();
|
||||
|
||||
DBObject pullAll = DBObjectTestUtils.getAsDBObject(updateObject, "$pullAll");
|
||||
|
||||
assertThat(pullAll.get("field1"), is(notNullValue()));
|
||||
assertThat(pullAll.get("field2"), is(notNullValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -661,6 +661,20 @@ public class MongoQueryCreatorUnitTests {
|
||||
assertThat(query, is(query(where("username").regex(".*"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1342
|
||||
*/
|
||||
@Test
|
||||
public void bindsNullValueToContainsClause() {
|
||||
|
||||
PartTree partTree = new PartTree("emailAddressesContains", User.class);
|
||||
|
||||
ConvertingParameterAccessor accessor = getAccessor(converter, new Object[] { null });
|
||||
Query query = new MongoQueryCreator(partTree, accessor, context).createQuery();
|
||||
|
||||
assertThat(query, is(query(where("emailAddresses").in((Object) null))));
|
||||
}
|
||||
|
||||
interface PersonRepository extends Repository<Person, Long> {
|
||||
|
||||
List<Person> findByLocationNearAndFirstname(Point location, Distance maxDistance, String firstname);
|
||||
|
||||
@@ -24,6 +24,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
import org.bson.BSON;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -343,6 +346,23 @@ public class StringBasedMongoQueryUnitTests {
|
||||
assertThat(query.getQueryObject(), is(reference.getQueryObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1290
|
||||
*/
|
||||
@Test
|
||||
public void shouldSupportNonQuotedBinaryDataReplacement() throws Exception {
|
||||
|
||||
byte[] binaryData = "Matthews".getBytes("UTF-8");
|
||||
ConvertingParameterAccessor accesor = StubParameterAccessor.getAccessor(converter, binaryData);
|
||||
StringBasedMongoQuery mongoQuery = createQueryForMethod("findByLastnameAsBinary", byte[].class);
|
||||
|
||||
org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accesor);
|
||||
org.springframework.data.mongodb.core.query.Query reference = new BasicQuery("{'lastname' : { '$binary' : '"
|
||||
+ DatatypeConverter.printBase64Binary(binaryData) + "', '$type' : " + BSON.B_GENERAL + "}}");
|
||||
|
||||
assertThat(query.getQueryObject(), is(reference.getQueryObject()));
|
||||
}
|
||||
|
||||
private StringBasedMongoQuery createQueryForMethod(String name, Class<?>... parameters) throws Exception {
|
||||
|
||||
Method method = SampleRepository.class.getMethod(name, parameters);
|
||||
@@ -355,6 +375,9 @@ public class StringBasedMongoQueryUnitTests {
|
||||
@Query("{ 'lastname' : ?0 }")
|
||||
Person findByLastname(String lastname);
|
||||
|
||||
@Query("{ 'lastname' : ?0 }")
|
||||
Person findByLastnameAsBinary(byte[] lastname);
|
||||
|
||||
@Query("{ 'lastname' : '?0' }")
|
||||
Person findByLastnameQuoted(String lastname);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ Import-Template:
|
||||
javax.tools.*;version="0",
|
||||
javax.net.*;version="0",
|
||||
javax.validation.*;version="${validation:[=.=.=.=,+1.0.0)}";resolution:=optional,
|
||||
javax.xml.bind.*;version=0,
|
||||
org.aopalliance.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
org.bson.*;version="0",
|
||||
org.objenesis.*;version="${objenesis:[=.=.=, +1.0.0)}";resolution:=optional,
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 1.8.2.RELEASE (2015-12-18)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-1355 - Release 1.8.2 (Gosling).
|
||||
* DATAMONGO-1346 - Cannot add two pullAll to an Update.
|
||||
* DATAMONGO-1342 - Potential NullPointerException in MongoQueryCreator.nextAsArray(…).
|
||||
* DATAMONGO-1337 - General code quality improvements.
|
||||
* DATAMONGO-1335 - DBObjectAccessor doesn't write properties correctly if multiple ones are nested.
|
||||
* DATAMONGO-1334 - MapResultOptions limit not implemented.
|
||||
* DATAMONGO-1324 - StringToObjectIdConverter not properly registered causing drop in performance on identifier conversion.
|
||||
* DATAMONGO-1317 - Assert compatibility with MongoDB Java driver 3.2.
|
||||
* DATAMONGO-1290 - @Query annotation with byte[] parameter does not work.
|
||||
* DATAMONGO-1289 - NullPointerException when saving an object with no "id" field or @Id annotation.
|
||||
* DATAMONGO-1287 - MappingMongoConverter eagerly fetches and converts lazy DbRef to change them afterwards by proxies.
|
||||
* DATAMONGO-1204 - ObjectPath equality check breaks due to changes MongoDB V3.
|
||||
|
||||
|
||||
Changes in version 1.8.1.RELEASE (2015-11-15)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-1316 - Release 1.8.1 (Gosling).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 1.8.1
|
||||
Spring Data MongoDB 1.8.2
|
||||
Copyright (c) [2010-2015] 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