Compare commits

..

12 Commits

Author SHA1 Message Date
Spring Buildmaster
f79636240c DATAMONGO-810 - Prepare Release 1.3.3.RELEASE. 2013-12-12 03:37:58 -08:00
Thomas Darimont
f22bf106db DATAMONGO-810 - Prepare Release 1.3.3.
Updated change log, notice, read me.
Updated SD Commons dependency to 1.6.3.RELEASE.
2013-12-12 12:11:39 +01:00
Oliver Gierke
ff72150518 DATAMONGO-806 - Fixed invalid rendering of id field references.
Tweaked the rendering of projection operations to always use the field based reference lookup to make sure the reference gets rendered aliased. Moved value calculation logic into FieldReference.

Original pull request: #101.
2013-12-09 16:41:10 +01:00
Martin Baumgartner
099689c00d DATAMONGO-726 - Fixed classname references in namespace XSDs.
Original pull request: #100.
2013-12-09 10:10:32 +01:00
Thomas Darimont
1d5df555f0 DATAMONGO-799 - Fix failing test in MongoTemplateTests on MongoDB 2.5.x.
Generalized exception message matching to reflect the changed exception message in MongoDB 2.5.x that also works with previous versions of MongoDB.

Original pull request: #97.
2013-12-04 12:39:59 +01:00
Thomas Darimont
54e6a80ca9 DATAMONGO-804 - Fix default annotation attribute value for repositoryImplementationPostfix().
Changed repositoryImplementationPostfix() in EnableMongoRepositories to "Impl" to be consistent with other EnableXXXRepositories annotations. Note that this change is of rather documenting nature, as the defaulting of the configuration is applied in DefaultRepositoryConfiguration.getImplementationPostfix() in Spring Data Commons.

Original pull request: #99.
2013-12-04 12:39:45 +01:00
Oliver Gierke
f66d773a94 DATAMONGO-800 - Improved AuditingIntegrationTests.
Added a tiny Thread.sleep(…) to make sure the assertion works on fast machines. If the operations after the first step all happen within a millisecond, it will fail.
2013-11-18 13:54:11 +01:00
Oliver Gierke
899afe1fe7 DATAMONGO-795 - More predictable behavior in CustomConversions.
The target type lookup previously was unpredictable in cases two converters were registered for the same source type. We now use LinkedHashMaps to register the converters and also make sure that we prefer manually registered converters over the default ones.

Related pull request: #96.
2013-11-07 15:12:13 +01:00
Thomas Darimont
ee9a6993b1 DATAMONGO-791 - Added newAggregation(…) overloads to accept a List.
Aggregations can now be constructed from a list of AggregateOperations. This simplifies the usage in cases where one has to conditionally in- or exclude AggregateOperations from an AggregationPipeline.

Original pull request: #93.
2013-11-06 10:57:50 +01:00
Oliver Gierke
5d7e12a4fa DATAMONGO-788 - Polishing.
Slightly changed the way the the simple reference rendering for projections is implemented. Introduced an isAliased() method on Field to be able to determine whether the field reference has been renamed explicitly.

Original pull request: #90.
2013-10-31 14:39:19 +00:00
Thomas Darimont
8b3da2d7f9 DATAMONGO-788 - Projection operations do not render synthetic fields properly.
Introduced boolean isSynthetic() attribute to FieldReference to determine if the given reference points to a synthetic field, as this controls whether we render a simple include (1) or a concrete reference ($fieldName) E.g. isSynthetic() would be true for a field reference to _id.

Original pull request: #90.
2013-10-31 14:39:11 +00:00
Spring Buildmaster
49af31bb6e DATAMONGO-772 - Prepare next development iteration. 2013-10-25 08:11:26 -07:00
31 changed files with 506 additions and 53 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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.
*

View File

@@ -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()

View File

@@ -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();
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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));
}
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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"));
}
}

View File

@@ -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"));
}

View File

@@ -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 "";
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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>

View File

@@ -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

View File

@@ -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").

View File

@@ -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).