Compare commits
12 Commits
1.3.2.RELE
...
1.3.3.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f79636240c | ||
|
|
f22bf106db | ||
|
|
ff72150518 | ||
|
|
099689c00d | ||
|
|
1d5df555f0 | ||
|
|
54e6a80ca9 | ||
|
|
f66d773a94 | ||
|
|
899afe1fe7 | ||
|
|
ee9a6993b1 | ||
|
|
5d7e12a4fa | ||
|
|
8b3da2d7f9 | ||
|
|
49af31bb6e |
4
pom.xml
4
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
<version>1.3.3.RELEASE</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Spring Data MongoDB</name>
|
||||
@@ -29,7 +29,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>1.6.2.RELEASE</springdata.commons>
|
||||
<springdata.commons>1.6.3.RELEASE</springdata.commons>
|
||||
<mongo>2.10.1</mongo>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
<version>1.3.3.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.2.RELEASE</version>
|
||||
<version>1.3.3.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>1.3.2.RELEASE</version>
|
||||
<version>1.3.3.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.2.RELEASE</version>
|
||||
<version>1.3.3.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.2.RELEASE</version>
|
||||
<version>1.3.3.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -48,6 +48,15 @@ public class Aggregation {
|
||||
|
||||
private final List<AggregationOperation> operations;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
|
||||
*
|
||||
* @param operations must not be {@literal null} or empty.
|
||||
*/
|
||||
public static Aggregation newAggregation(List<? extends AggregationOperation> operations) {
|
||||
return newAggregation(operations.toArray(new AggregationOperation[operations.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Aggregation} from the given {@link AggregationOperation}s.
|
||||
*
|
||||
@@ -57,6 +66,16 @@ public class Aggregation {
|
||||
return new Aggregation(operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TypedAggregation} for the given type and {@link AggregationOperation}s.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @param operations must not be {@literal null} or empty.
|
||||
*/
|
||||
public static <T> TypedAggregation<T> newAggregation(Class<T> type, List<? extends AggregationOperation> operations) {
|
||||
return newAggregation(type, operations.toArray(new AggregationOperation[operations.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link TypedAggregation} for the given type and {@link AggregationOperation}s.
|
||||
*
|
||||
|
||||
@@ -259,6 +259,15 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
return field.getTarget();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.Field#isAliased()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAliased() {
|
||||
return field.isAliased();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the field can be referred to using the given name.
|
||||
*
|
||||
@@ -344,6 +353,16 @@ public class ExposedFields implements Iterable<ExposedField> {
|
||||
return field.synthetic ? target : String.format("%s.%s", Fields.UNDERSCORE_ID, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the referenve value for the given field reference. Will return 1 for a synthetic, unaliased field or the
|
||||
* raw rendering of the reference otherwise.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Object getReferenceValue() {
|
||||
return field.synthetic && !field.isAliased() ? 1 : toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
@@ -36,4 +36,11 @@ public interface Field {
|
||||
* @return must not be {@literal null}.
|
||||
*/
|
||||
String getTarget();
|
||||
|
||||
/**
|
||||
* Returns whether the Field is aliased, which means it has a name set different from the target.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isAliased();
|
||||
}
|
||||
|
||||
@@ -224,6 +224,15 @@ public class Fields implements Iterable<Field> {
|
||||
return StringUtils.hasText(this.target) ? this.target : this.name;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.Field#isAliased()
|
||||
*/
|
||||
@Override
|
||||
public boolean isAliased() {
|
||||
return !getName().equals(getTarget());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.FieldReference;
|
||||
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder.FieldProjection;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -506,16 +505,8 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
|
||||
if (value == null || Boolean.TRUE.equals(value)) {
|
||||
|
||||
// check whether referenced field exists in the context
|
||||
FieldReference reference = context.getReference(field.getTarget());
|
||||
return context.getReference(field).getReferenceValue();
|
||||
|
||||
if (field.getName().equals(field.getTarget())) {
|
||||
|
||||
// render field as included
|
||||
return 1;
|
||||
}
|
||||
|
||||
// render field reference
|
||||
return reference.toString();
|
||||
} else if (Boolean.FALSE.equals(value)) {
|
||||
|
||||
// render field as excluded
|
||||
|
||||
@@ -88,15 +88,17 @@ public class TypeBasedAggregationOperationContext implements AggregationOperatio
|
||||
*/
|
||||
@Override
|
||||
public FieldReference getReference(String name) {
|
||||
PropertyPath path = PropertyPath.from(name, type);
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext.getPersistentPropertyPath(path);
|
||||
|
||||
return getReferenceFor(field(path.getLeafProperty().getSegment(),
|
||||
propertyPath.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE)));
|
||||
return getReferenceFor(field(name));
|
||||
}
|
||||
|
||||
private FieldReference getReferenceFor(Field field) {
|
||||
return new FieldReference(new ExposedField(field, true));
|
||||
|
||||
PropertyPath path = PropertyPath.from(field.getTarget(), type);
|
||||
|
||||
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext.getPersistentPropertyPath(path);
|
||||
Field mappedField = field(propertyPath.getLeafProperty().getName(),
|
||||
propertyPath.toDotPath(MongoPersistentProperty.PropertyToFieldNameConverter.INSTANCE));
|
||||
|
||||
return new FieldReference(new ExposedField(mappedField, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -86,12 +87,13 @@ public class CustomConversions {
|
||||
|
||||
Assert.notNull(converters);
|
||||
|
||||
this.readingPairs = new HashSet<ConvertiblePair>();
|
||||
this.writingPairs = new HashSet<ConvertiblePair>();
|
||||
this.readingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.writingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.customSimpleTypes = new HashSet<Class<?>>();
|
||||
this.cache = new HashMap<Class<?>, HashMap<Class<?>, CacheValue>>();
|
||||
|
||||
this.converters = new ArrayList<Object>();
|
||||
this.converters.addAll(converters);
|
||||
this.converters.add(CustomToStringConverter.INSTANCE);
|
||||
this.converters.add(BigDecimalToStringConverter.INSTANCE);
|
||||
this.converters.add(StringToBigDecimalConverter.INSTANCE);
|
||||
@@ -101,7 +103,6 @@ public class CustomConversions {
|
||||
this.converters.add(StringToURLConverter.INSTANCE);
|
||||
this.converters.add(DBObjectToStringConverter.INSTANCE);
|
||||
this.converters.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
this.converters.addAll(converters);
|
||||
|
||||
for (Object c : this.converters) {
|
||||
registerConversion(c);
|
||||
@@ -239,6 +240,7 @@ public class CustomConversions {
|
||||
* @return
|
||||
*/
|
||||
public Class<?> getCustomWriteTarget(Class<?> source, Class<?> expectedTargetType) {
|
||||
|
||||
Assert.notNull(source);
|
||||
return getCustomTarget(source, expectedTargetType, writingPairs);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public @interface EnableMongoRepositories {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String repositoryImplementationPostfix() default "";
|
||||
String repositoryImplementationPostfix() default "Impl";
|
||||
|
||||
/**
|
||||
* Configures the location of where to find the Spring Data named queries properties file. Will default to
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
|
||||
Defines a Mongo instance used for accessing MongoDB'.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -209,7 +209,7 @@ The base package in which to scan for entities annotated with @Document
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -248,7 +248,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -259,7 +259,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
|
||||
Defines a Mongo instance used for accessing MongoDB'.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -197,7 +197,7 @@ The base package in which to scan for entities annotated with @Document
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -246,7 +246,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -257,7 +257,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
|
||||
Defines a Mongo instance used for accessing MongoDB'.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -197,7 +197,7 @@ The base package in which to scan for entities annotated with @Document
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoTemplate">
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoTemplate">
|
||||
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -261,7 +261,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -272,7 +272,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<xsd:element name="mongo" type="mongoType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.core.MongoFactoryBean"><![CDATA[
|
||||
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
|
||||
Defines a Mongo instance used for accessing MongoDB'.
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
@@ -276,7 +276,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoTemplate"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
@@ -287,7 +287,7 @@ The name of the Mongo object that determines what server to monitor. (by default
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.core.MongoFactoryBean"/>
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
|
||||
public class AuditingIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void enablesAuditingAndSetsPropertiesAccordingly() {
|
||||
public void enablesAuditingAndSetsPropertiesAccordingly() throws Exception {
|
||||
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("auditing.xml", getClass());
|
||||
|
||||
@@ -46,6 +46,7 @@ public class AuditingIntegrationTests {
|
||||
assertThat(entity.created, is(notNullValue()));
|
||||
assertThat(entity.modified, is(entity.created));
|
||||
|
||||
Thread.sleep(10);
|
||||
entity.id = 1L;
|
||||
event = new BeforeConvertEvent<Entity>(entity);
|
||||
context.publishEvent(event);
|
||||
|
||||
@@ -213,6 +213,7 @@ public class MongoTemplateTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-480
|
||||
* @see DATAMONGO-799
|
||||
*/
|
||||
@Test
|
||||
public void throwsExceptionForUpdateWithInvalidPushOperator() {
|
||||
@@ -228,8 +229,10 @@ public class MongoTemplateTests {
|
||||
|
||||
thrown.expect(DataIntegrityViolationException.class);
|
||||
thrown.expectMessage("Execution");
|
||||
thrown.expectMessage("$push");
|
||||
thrown.expectMessage("UPDATE");
|
||||
thrown.expectMessage("array");
|
||||
thrown.expectMessage("firstName");
|
||||
thrown.expectMessage("failed");
|
||||
|
||||
Query query = new Query(Criteria.where("firstName").is("Amol"));
|
||||
Update upd = new Update().push("age", 29);
|
||||
|
||||
@@ -23,10 +23,12 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -36,6 +38,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.CollectionCallback;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -85,6 +88,7 @@ public class AggregationTests {
|
||||
mongoTemplate.dropCollection(Product.class);
|
||||
mongoTemplate.dropCollection(UserWithLikes.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO753.class);
|
||||
mongoTemplate.dropCollection(DATAMONGO788.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -520,6 +524,70 @@ public class AggregationTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-788
|
||||
*/
|
||||
@Test
|
||||
public void referencesToGroupIdsShouldBeRenderedProperly() {
|
||||
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(1, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(2, 1));
|
||||
mongoTemplate.insert(new DATAMONGO788(2, 1));
|
||||
|
||||
AggregationOperation projectFirst = Aggregation.project("x", "y").and("xField").as("x").and("yField").as("y");
|
||||
AggregationOperation group = Aggregation.group("x", "y").count().as("xPerY");
|
||||
AggregationOperation project = Aggregation.project("xPerY", "x", "y").andExclude("_id");
|
||||
|
||||
TypedAggregation<DATAMONGO788> aggregation = Aggregation.newAggregation(DATAMONGO788.class, projectFirst, group,
|
||||
project);
|
||||
AggregationResults<DBObject> aggResults = mongoTemplate.aggregate(aggregation, DBObject.class);
|
||||
List<DBObject> items = aggResults.getMappedResults();
|
||||
|
||||
assertThat(items.size(), is(2));
|
||||
assertThat((Integer) items.get(0).get("xPerY"), is(2));
|
||||
assertThat((Integer) items.get(0).get("x"), is(2));
|
||||
assertThat((Integer) items.get(0).get("y"), is(1));
|
||||
assertThat((Integer) items.get(1).get("xPerY"), is(3));
|
||||
assertThat((Integer) items.get(1).get("x"), is(1));
|
||||
assertThat((Integer) items.get(1).get("y"), is(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-806
|
||||
*/
|
||||
@Test
|
||||
public void shouldAllowGroupByIdFields() {
|
||||
|
||||
mongoTemplate.dropCollection(User.class);
|
||||
|
||||
LocalDateTime now = new LocalDateTime();
|
||||
|
||||
User user1 = new User("u1", new PushMessage("1", "aaa", now.toDate()));
|
||||
User user2 = new User("u2", new PushMessage("2", "bbb", now.minusDays(2).toDate()));
|
||||
User user3 = new User("u3", new PushMessage("3", "ccc", now.minusDays(1).toDate()));
|
||||
|
||||
mongoTemplate.save(user1);
|
||||
mongoTemplate.save(user2);
|
||||
mongoTemplate.save(user3);
|
||||
|
||||
Aggregation agg = newAggregation( //
|
||||
project("id", "msgs"), //
|
||||
unwind("msgs"), //
|
||||
match(where("msgs.createDate").gt(now.minusDays(1).toDate())), //
|
||||
group("id").push("msgs").as("msgs") //
|
||||
);
|
||||
|
||||
AggregationResults<DBObject> results = mongoTemplate.aggregate(agg, User.class, DBObject.class);
|
||||
|
||||
List<DBObject> mappedResults = results.getMappedResults();
|
||||
|
||||
DBObject firstItem = mappedResults.get(0);
|
||||
assertThat(firstItem.get("_id"), is(notNullValue()));
|
||||
assertThat(String.valueOf(firstItem.get("_id")), is("u1"));
|
||||
}
|
||||
|
||||
private void assertLikeStats(LikeStats like, String id, long count) {
|
||||
|
||||
assertThat(like, is(notNullValue()));
|
||||
@@ -585,4 +653,55 @@ public class AggregationTests {
|
||||
this.up = up;
|
||||
}
|
||||
}
|
||||
|
||||
static class DATAMONGO788 {
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int xField;
|
||||
int yField;
|
||||
|
||||
public DATAMONGO788() {}
|
||||
|
||||
public DATAMONGO788(int x, int y) {
|
||||
this.x = x;
|
||||
this.xField = x;
|
||||
this.y = y;
|
||||
this.yField = y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-806
|
||||
*/
|
||||
static class User {
|
||||
|
||||
@Id String id;
|
||||
List<PushMessage> msgs;
|
||||
|
||||
public User() {}
|
||||
|
||||
public User(String id, PushMessage... msgs) {
|
||||
this.id = id;
|
||||
this.msgs = Arrays.asList(msgs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-806
|
||||
*/
|
||||
static class PushMessage {
|
||||
|
||||
@Id String id;
|
||||
String content;
|
||||
Date createDate;
|
||||
|
||||
public PushMessage() {}
|
||||
|
||||
public PushMessage(String id, String content, Date createDate) {
|
||||
this.id = id;
|
||||
this.content = content;
|
||||
this.createDate = createDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,21 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.DBObjectUtils.*;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Aggregation}.
|
||||
*
|
||||
@@ -94,4 +102,63 @@ public class AggregationUnitTests {
|
||||
project("a", "b") // b should still be available
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-788
|
||||
*/
|
||||
@Test
|
||||
public void referencesToGroupIdsShouldBeRenderedAsReferences() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
project("a"), //
|
||||
group("a").count().as("aCnt"), //
|
||||
project("aCnt", "a") //
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject secondProjection = ((List<DBObject>) agg.get("pipeline")).get(2);
|
||||
DBObject fields = getAsDBObject(secondProjection, "$project");
|
||||
assertThat(fields.get("aCnt"), is((Object) 1));
|
||||
assertThat(fields.get("a"), is((Object) "$_id.a"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-791
|
||||
*/
|
||||
@Test
|
||||
public void allowAggregationOperationsToBePassedAsIterable() {
|
||||
|
||||
List<AggregationOperation> ops = new ArrayList<AggregationOperation>();
|
||||
ops.add(project("a"));
|
||||
ops.add(group("a").count().as("aCnt"));
|
||||
ops.add(project("aCnt", "a"));
|
||||
|
||||
DBObject agg = newAggregation(ops).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject secondProjection = ((List<DBObject>) agg.get("pipeline")).get(2);
|
||||
DBObject fields = getAsDBObject(secondProjection, "$project");
|
||||
assertThat(fields.get("aCnt"), is((Object) 1));
|
||||
assertThat(fields.get("a"), is((Object) "$_id.a"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-791
|
||||
*/
|
||||
@Test
|
||||
public void allowTypedAggregationOperationsToBePassedAsIterable() {
|
||||
|
||||
List<AggregationOperation> ops = new ArrayList<AggregationOperation>();
|
||||
ops.add(project("a"));
|
||||
ops.add(group("a").count().as("aCnt"));
|
||||
ops.add(project("aCnt", "a"));
|
||||
|
||||
DBObject agg = newAggregation(DBObject.class, ops).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject secondProjection = ((List<DBObject>) agg.get("pipeline")).get(2);
|
||||
DBObject fields = getAsDBObject(secondProjection, "$project");
|
||||
assertThat(fields.get("aCnt"), is((Object) 1));
|
||||
assertThat(fields.get("a"), is((Object) "$_id.a"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class ProjectionOperationUnitTests {
|
||||
DBObject dbObject = operation.toDBObject(Aggregation.DEFAULT_CONTEXT);
|
||||
DBObject projectClause = DBObjectUtils.getAsDBObject(dbObject, PROJECT);
|
||||
|
||||
assertThat((Integer) projectClause.get("foo"), is(1));
|
||||
assertThat(projectClause.get("foo"), is((Object) 1));
|
||||
assertThat(projectClause.get("bar"), is((Object) "$foobar"));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.util.UUID;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
@@ -172,6 +173,17 @@ public class CustomConversionsUnitTests {
|
||||
assertThat(conversions.hasCustomReadTarget(String.class, URL.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-795
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void favorsCustomConverterForIndeterminedTargetType() {
|
||||
|
||||
CustomConversions conversions = new CustomConversions(Arrays.asList(DateTimeToStringConverter.INSTANCE));
|
||||
assertThat(conversions.getCustomWriteTarget(DateTime.class, null), is(equalTo((Class) String.class)));
|
||||
}
|
||||
|
||||
enum FormatToStringConverter implements Converter<Format, String> {
|
||||
INSTANCE;
|
||||
|
||||
@@ -207,4 +219,13 @@ public class CustomConversionsUnitTests {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
enum DateTimeToStringConverter implements Converter<DateTime, String> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public String convert(DateTime source) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,14 @@ import org.springframework.data.mongodb.core.mapping.Document;
|
||||
@Document
|
||||
public class User {
|
||||
|
||||
@Id
|
||||
String id;
|
||||
@Id String id;
|
||||
String username;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.repository.custom;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface CustomMongoRepository extends Repository<User, String> {
|
||||
|
||||
List<User> findByUsernameCustom(String username);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.repository.custom;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public class CustomMongoRepositoryImpl implements CustomMongoRepository {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.repository.custom.CustomMongoRepository#findByFullName()
|
||||
*/
|
||||
@Override
|
||||
public List<User> findByUsernameCustom(String username) {
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(username);
|
||||
return Arrays.asList(user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.repository.custom;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.context.annotation.ImportResource;
|
||||
import org.springframework.data.mongodb.repository.User;
|
||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Integration tests for custom Repository implementations.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class CustomRepositoryImplementationTests {
|
||||
|
||||
@Configuration
|
||||
@EnableMongoRepositories
|
||||
@ImportResource("classpath:infrastructure.xml")
|
||||
static class Config {}
|
||||
|
||||
@Autowired CustomMongoRepository customMongoRepository;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-804
|
||||
*/
|
||||
@Test
|
||||
public void shouldExecuteMethodOnCustomRepositoryImplementation() {
|
||||
|
||||
String username = "bubu";
|
||||
List<User> users = customMongoRepository.findByUsernameCustom(username);
|
||||
|
||||
assertThat(users.size(), is(1));
|
||||
assertThat(users.get(0), is(notNullValue()));
|
||||
assertThat(users.get(0).getUsername(), is(username));
|
||||
}
|
||||
}
|
||||
@@ -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.2.RELEASE/src/docbkx/repositories.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.3.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.2.RELEASE/src/docbkx/repository-namespace-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.3.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.2.RELEASE/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:include href="https://raw.github.com/SpringSource/spring-data-commons/1.6.3.RELEASE/src/docbkx/repository-query-keywords-reference.xml">
|
||||
<xi:fallback href="../../../spring-data-commons/src/docbkx/repository-query-keywords-reference.xml" />
|
||||
</xi:include>
|
||||
</part>
|
||||
|
||||
@@ -1,6 +1,62 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 1.3.3.RELEASE (2013-12-11)
|
||||
---------------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-726] - Fixed classname references in namespace XSDs.
|
||||
* [DATAMONGO-788] - Projection operations do not render synthetic fields properly.
|
||||
* [DATAMONGO-795] - When adding custom converters to the mongo template it is possible to get unpredictable behaviour
|
||||
* [DATAMONGO-804] - Fix default annotation attribute value for repositoryImplementationPostfix().
|
||||
* [DATAMONGO-806] - Fixed invalid rendering of id field references.
|
||||
* [DATAMONGO-768] - Improve documentation of how to use @PersistenceConstructor
|
||||
|
||||
** Improvement
|
||||
* [DATAMONGO-791] - Added newAggregation(…) overloads to accept a List.
|
||||
* [DATAMONGO-799] - Fix failing test in MongoTemplateTests on Mongo 2.5.x
|
||||
* [DATAMONGO-800] - Improved AuditingIntegrationTests.
|
||||
** Task
|
||||
* [DATAMONGO-810] - Release 1.3.3
|
||||
|
||||
Changes in version 1.4.0.M1 (2013-11-19)
|
||||
---------------------------------------------
|
||||
** Bug
|
||||
* [DATAMONGO-534] - The GridFs query execution does not return sorted resources, when the sorting fields are defined in the query definition
|
||||
* [DATAMONGO-630] - Add support of $setOnInsert modifier for upsert
|
||||
* [DATAMONGO-746] - IndexInfo cannot be read for indices created via mongo shell
|
||||
* [DATAMONGO-752] - QueryMapper prevents searching for values that start with a $ [dollarsign]
|
||||
* [DATAMONGO-753] - Add support for nested field references in group operations
|
||||
* [DATAMONGO-758] - Reject excludes other than _id in projection operations
|
||||
* [DATAMONGO-759] - Render group operation without non synthetic fields correctly.
|
||||
* [DATAMONGO-761] - ClassCastException in SpringDataMongodbSerializer.getKeyForPath
|
||||
* [DATAMONGO-768] - Improve documentation of how to use @PersistenceConstructor
|
||||
* [DATAMONGO-788] - Projection operations do not render synthetic fields properly.
|
||||
* [DATAMONGO-789] - Support login via different (e.g. admin) authentication database
|
||||
* [DATAMONGO-795] - When adding custom converters to the mongo template it is possible to get unpredictable behaviour
|
||||
** Improvement
|
||||
* [DATAMONGO-757] - Projections should follow mongodb conventions more precisely.
|
||||
* [DATAMONGO-764] - Add support for SSL connections to Mongo
|
||||
* [DATAMONGO-766] - Allow nested field references on properties through e.g. @Field("a.b")
|
||||
* [DATAMONGO-769] - Support arithmetic operators for properties
|
||||
* [DATAMONGO-770] - Repository - findBy<Field>IgnoreCase doesnt work
|
||||
* [DATAMONGO-771] - Saving raw JSON through MongoTemplate.insert(…) fails
|
||||
* [DATAMONGO-774] - Support SpEL expressions to define arithmetical projection operations in the aggregation framework
|
||||
* [DATAMONGO-776] - TypeBasedAggregationOperationContext should use MappingContext.getPersistentPropertyPath(String, Class<?>)
|
||||
* [DATAMONGO-780] - Add support for nested repositories
|
||||
* [DATAMONGO-782] - Typo in reference documentation
|
||||
* [DATAMONGO-785] - Add support for geospatial 2Dsphere and geohaystack index types
|
||||
* [DATAMONGO-787] - Upgrade to Spring 3.2.4
|
||||
* [DATAMONGO-791] - make newAggregation() method to accept list
|
||||
* [DATAMONGO-793] - Adapt to changes in Spring Data Commons triggered by repository initialization changes
|
||||
* [DATAMONGO-800] - AuditingIntegrationTests fail on fast machines
|
||||
** New Feature
|
||||
* [DATAMONGO-348] - Lazy Load for DbRef
|
||||
* [DATAMONGO-653] - Support for index operations in GridFsOperations
|
||||
* [DATAMONGO-760] - Add support for custom findAll Queries
|
||||
* [DATAMONGO-792] - Add support to configure Auditing via JavaConfig.
|
||||
** Task
|
||||
* [DATAMONGO-777] - Upgrade to Mongo Java Driver in 2.11
|
||||
|
||||
Changes in version 1.3.2.RELEASE (2013-10-25)
|
||||
---------------------------------------------
|
||||
** Bug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data Document 1.3.2.RELEASE
|
||||
Spring Data Document 1.3.3.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.2.RELEASE
|
||||
SPRING DATA MongoDB 1.3.3.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