Compare commits
21 Commits
issue/4379
...
2.1.2.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e25b6c49f5 | ||
|
|
7a70c205de | ||
|
|
6045efa450 | ||
|
|
7b0816b3ee | ||
|
|
14e4ea736d | ||
|
|
32e7d9ab7f | ||
|
|
7f35ad9e45 | ||
|
|
60228f6e5a | ||
|
|
7604492b7f | ||
|
|
4680fe0e77 | ||
|
|
b4228c88d3 | ||
|
|
f6ef8c94c8 | ||
|
|
0d0dafa85e | ||
|
|
29aa34619f | ||
|
|
7f19f769c4 | ||
|
|
a40e89d90a | ||
|
|
6b2350200a | ||
|
|
fb50b0f6e7 | ||
|
|
ab568229b5 | ||
|
|
7f9c1bd774 | ||
|
|
670a0978da |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.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>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -27,7 +27,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>2.1.0.RELEASE</springdata.commons>
|
||||
<springdata.commons>2.1.2.RELEASE</springdata.commons>
|
||||
<mongo>3.8.2</mongo>
|
||||
<mongo.reactivestreams>1.9.2</mongo.reactivestreams>
|
||||
<jmh.version>1.19</jmh.version>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- reactive -->
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>2.1.0.RELEASE</version>
|
||||
<version>2.1.2.RELEASE</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCre
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -75,6 +76,7 @@ import org.w3c.dom.Element;
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Zied Yaich
|
||||
*/
|
||||
public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
|
||||
@@ -159,6 +161,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
|
||||
|
||||
String disableValidation = element.getAttribute("disable-validation");
|
||||
@@ -180,6 +183,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private RuntimeBeanReference getValidator(Object source, ParserContext parserContext) {
|
||||
|
||||
if (!JSR_303_PRESENT) {
|
||||
@@ -197,7 +201,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
|
||||
BeanDefinition conversionsDefinition, String converterId) {
|
||||
@Nullable BeanDefinition conversionsDefinition, @Nullable String converterId) {
|
||||
|
||||
String ctxRef = element.getAttribute("mapping-context-ref");
|
||||
|
||||
@@ -211,7 +215,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MongoMappingContext.class);
|
||||
|
||||
Set<String> classesToAdd = getInititalEntityClasses(element);
|
||||
Set<String> classesToAdd = getInitialEntityClasses(element);
|
||||
|
||||
if (classesToAdd != null) {
|
||||
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
|
||||
@@ -262,6 +266,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
|
||||
|
||||
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
|
||||
@@ -269,7 +274,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
if (customConvertersElements.size() == 1) {
|
||||
|
||||
Element customerConvertersElement = customConvertersElements.get(0);
|
||||
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
|
||||
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<>();
|
||||
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
|
||||
|
||||
if (converterElements != null) {
|
||||
@@ -285,9 +290,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class),
|
||||
new AssignableTypeFilter(GenericConverter.class)));
|
||||
|
||||
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
|
||||
converterBeans.add(candidate);
|
||||
}
|
||||
converterBeans.addAll(provider.findCandidateComponents(packageToScan));
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(MongoCustomConversions.class);
|
||||
@@ -304,7 +307,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Set<String> getInititalEntityClasses(Element element) {
|
||||
@Nullable
|
||||
private static Set<String> getInitialEntityClasses(Element element) {
|
||||
|
||||
String basePackage = element.getAttribute(BASE_PACKAGE);
|
||||
|
||||
@@ -317,7 +321,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
|
||||
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
|
||||
|
||||
Set<String> classes = new ManagedSet<String>();
|
||||
Set<String> classes = new ManagedSet<>();
|
||||
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
|
||||
classes.add(candidate.getBeanClassName());
|
||||
}
|
||||
@@ -325,6 +329,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BeanMetadataElement parseConverter(Element element, ParserContext parserContext) {
|
||||
|
||||
String converterRef = element.getAttribute("ref");
|
||||
@@ -375,7 +380,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
|
||||
|
||||
Assert.notNull(filters, "TypeFilters must not be null");
|
||||
|
||||
this.delegates = new HashSet<TypeFilter>(Arrays.asList(filters));
|
||||
this.delegates = new HashSet<>(Arrays.asList(filters));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -83,7 +83,9 @@ public class ChangeStreamEvent<T> {
|
||||
*/
|
||||
@Nullable
|
||||
public Instant getTimestamp() {
|
||||
return raw != null && raw.getClusterTime() != null ? Instant.ofEpochMilli(raw.getClusterTime().getValue()) : null;
|
||||
|
||||
return raw != null && raw.getClusterTime() != null
|
||||
? converter.getConversionService().convert(raw.getClusterTime(), Instant.class) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1915,7 +1915,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
publisher = options.getResumeToken().map(BsonValue::asDocument).map(publisher::resumeAfter).orElse(publisher);
|
||||
publisher = options.getCollation().map(Collation::toMongoCollation).map(publisher::collation).orElse(publisher);
|
||||
publisher = options.getResumeTimestamp().map(it -> new BsonTimestamp(it.toEpochMilli()))
|
||||
publisher = options.getResumeTimestamp().map(it -> new BsonTimestamp((int) it.getEpochSecond(), 0))
|
||||
.map(publisher::startAtOperationTime).orElse(publisher);
|
||||
publisher = publisher.fullDocument(options.getFullDocumentLookup().orElse(fullDocument));
|
||||
|
||||
|
||||
@@ -103,8 +103,8 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation
|
||||
|
||||
graphLookup.put("startWith", mappedStartWith.size() == 1 ? mappedStartWith.iterator().next() : mappedStartWith);
|
||||
|
||||
graphLookup.put("connectFromField", connectFrom.getName());
|
||||
graphLookup.put("connectToField", connectTo.getName());
|
||||
graphLookup.put("connectFromField", connectFrom.getTarget());
|
||||
graphLookup.put("connectToField", connectTo.getTarget());
|
||||
graphLookup.put("as", as.getName());
|
||||
|
||||
if (maxDepth != null) {
|
||||
@@ -112,7 +112,7 @@ public class GraphLookupOperation implements InheritsFieldsAggregationOperation
|
||||
}
|
||||
|
||||
if (depthField != null) {
|
||||
graphLookup.put("depthField", depthField.getName());
|
||||
graphLookup.put("depthField", depthField.getTarget());
|
||||
}
|
||||
|
||||
if (restrictSearchWithMatch != null) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Currency;
|
||||
@@ -26,6 +27,7 @@ import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.bson.BsonTimestamp;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.Code;
|
||||
@@ -86,6 +88,7 @@ abstract class MongoConverters {
|
||||
converters.add(LongToAtomicLongConverter.INSTANCE);
|
||||
converters.add(IntegerToAtomicIntegerConverter.INSTANCE);
|
||||
converters.add(BinaryToByteArrayConverter.INSTANCE);
|
||||
converters.add(BsonTimestampToInstantConverter.INSTANCE);
|
||||
|
||||
return converters;
|
||||
}
|
||||
@@ -465,4 +468,22 @@ abstract class MongoConverters {
|
||||
return source.getData();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Converter} implementation converting {@link BsonTimestamp} into {@link Instant}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.1.2
|
||||
*/
|
||||
@ReadingConverter
|
||||
enum BsonTimestampToInstantConverter implements Converter<BsonTimestamp, Instant> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Instant convert(BsonTimestamp source) {
|
||||
return Instant.ofEpochSecond(source.getTime(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ class ChangeStreamTask extends CursorReadingTask<ChangeStreamDocument<Document>,
|
||||
.orElseGet(() -> ClassUtils.isAssignable(Document.class, targetType) ? FullDocument.DEFAULT
|
||||
: FullDocument.UPDATE_LOOKUP);
|
||||
|
||||
startAt = changeStreamOptions.getResumeTimestamp().map(Instant::toEpochMilli).map(BsonTimestamp::new)
|
||||
startAt = changeStreamOptions.getResumeTimestamp().map(it -> new BsonTimestamp((int) it.getEpochSecond(), 0))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -1355,7 +1356,7 @@ public class ReactiveMongoTemplateTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2012
|
||||
@Test // DATAMONGO-2012, DATAMONGO-2113
|
||||
public void resumesAtTimestampCorrectly() throws InterruptedException {
|
||||
|
||||
Assumptions.assumeThat(ReplicaSet.required().runsAsReplicaSet()).isTrue();
|
||||
@@ -1372,7 +1373,7 @@ public class ReactiveMongoTemplateTests {
|
||||
Person person2 = new Person("Data", 37);
|
||||
Person person3 = new Person("MongoDB", 39);
|
||||
|
||||
StepVerifier.create(template.save(person1)).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(template.save(person1).delayElement(Duration.ofSeconds(1))).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(template.save(person2)).expectNextCount(1).verifyComplete();
|
||||
|
||||
Thread.sleep(500); // just give it some time to link receive all events
|
||||
|
||||
@@ -15,19 +15,15 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.core.Is.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
|
||||
import static org.springframework.data.mongodb.test.util.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.Person;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import com.mongodb.util.JSON;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GraphLookupOperation}.
|
||||
*
|
||||
@@ -54,8 +50,7 @@ public class GraphLookupOperationUnitTests {
|
||||
.as("reportingHierarchy");
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
assertThat(document,
|
||||
isBsonObject().containing("$graphLookup.depthField", "depth").containing("$graphLookup.maxDepth", 42L));
|
||||
assertThat(document).containsEntry("$graphLookup.depthField", "depth").containsEntry("$graphLookup.maxDepth", 42L);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1551
|
||||
@@ -70,8 +65,7 @@ public class GraphLookupOperationUnitTests {
|
||||
.as("reportingHierarchy");
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
assertThat(document,
|
||||
isBsonObject().containing("$graphLookup.restrictSearchWithMatch", new Document("key", "value")));
|
||||
assertThat(document).containsEntry("$graphLookup.restrictSearchWithMatch", new Document("key", "value"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1551
|
||||
@@ -86,9 +80,9 @@ public class GraphLookupOperationUnitTests {
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document,
|
||||
is(Document.parse("{ $graphLookup : { from: \"employees\", startWith: [\"$reportsTo\", \"$boss\"], "
|
||||
+ "connectFromField: \"reportsTo\", connectToField: \"name\", as: \"reportingHierarchy\" } }")));
|
||||
assertThat(document)
|
||||
.isEqualTo(Document.parse("{ $graphLookup : { from: \"employees\", startWith: [\"$reportsTo\", \"$boss\"], "
|
||||
+ "connectFromField: \"reportsTo\", connectToField: \"name\", as: \"reportingHierarchy\" } }"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1551
|
||||
@@ -103,9 +97,8 @@ public class GraphLookupOperationUnitTests {
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document,
|
||||
is(Document.parse("{ $graphLookup : { from: \"employees\", startWith: [\"$reportsTo\", { $literal: \"$boss\"}], "
|
||||
+ "connectFromField: \"reportsTo\", connectToField: \"name\", as: \"reportingHierarchy\" } }")));
|
||||
assertThat(document).containsEntry("$graphLookup.startWith",
|
||||
Arrays.asList("$reportsTo", new Document("$literal", "$boss")));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) // DATAMONGO-1551
|
||||
@@ -131,7 +124,39 @@ public class GraphLookupOperationUnitTests {
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document, is(Document.parse("{ $graphLookup : { from: \"employees\", startWith: { $literal: \"hello\"}, "
|
||||
+ "connectFromField: \"reportsTo\", connectToField: \"name\", as: \"reportingHierarchy\" } }")));
|
||||
assertThat(document).containsEntry("$graphLookup.startWith", new Document("$literal", "hello"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2096
|
||||
public void connectFromShouldUseTargetFieldInsteadOfAlias() {
|
||||
|
||||
AggregationOperation graphLookupOperation = Aggregation.graphLookup("user").startWith("contacts.userId")
|
||||
.connectFrom("contacts.userId").connectTo("_id").depthField("numConnections").as("connections");
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document).containsEntry("$graphLookup.startWith", "$contacts.userId");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2096
|
||||
public void connectToShouldUseTargetFieldInsteadOfAlias() {
|
||||
|
||||
AggregationOperation graphLookupOperation = Aggregation.graphLookup("user").startWith("contacts.userId")
|
||||
.connectFrom("userId").connectTo("connectto.field").depthField("numConnections").as("connections");
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document).containsEntry("$graphLookup.connectToField", "connectto.field");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2096
|
||||
public void depthFieldShouldUseTargetFieldInsteadOfAlias() {
|
||||
|
||||
AggregationOperation graphLookupOperation = Aggregation.graphLookup("user").startWith("contacts.userId")
|
||||
.connectFrom("contacts.userId").connectTo("_id").depthField("foo.bar").as("connections");
|
||||
|
||||
Document document = graphLookupOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(document).containsEntry("$graphLookup.depthField", "foo.bar");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,14 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Currency;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.assertj.core.data.TemporalUnitLessThanOffset;
|
||||
import org.bson.BsonTimestamp;
|
||||
import org.bson.Document;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.geo.Box;
|
||||
import org.springframework.data.geo.Circle;
|
||||
@@ -32,6 +36,7 @@ import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.AtomicIntegerToIntegerConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.AtomicLongToLongConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.BsonTimestampToInstantConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.CurrencyToStringConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.IntegerToAtomicIntegerConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.LongToAtomicLongConverter;
|
||||
@@ -39,8 +44,6 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBig
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToCurrencyConverter;
|
||||
import org.springframework.data.mongodb.core.geo.Sphere;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MongoConverters}.
|
||||
*
|
||||
@@ -55,10 +58,10 @@ public class MongoConvertersUnitTests {
|
||||
|
||||
BigDecimal bigDecimal = BigDecimal.valueOf(254, 1);
|
||||
String value = BigDecimalToStringConverter.INSTANCE.convert(bigDecimal);
|
||||
assertThat(value, is("25.4"));
|
||||
assertThat(value).isEqualTo("25.4");
|
||||
|
||||
BigDecimal reference = StringToBigDecimalConverter.INSTANCE.convert(value);
|
||||
assertThat(reference, is(bigDecimal));
|
||||
assertThat(reference).isEqualTo(bigDecimal);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-858
|
||||
@@ -69,7 +72,7 @@ public class MongoConvertersUnitTests {
|
||||
Document document = GeoConverters.BoxToDocumentConverter.INSTANCE.convert(box);
|
||||
Shape shape = GeoConverters.DocumentToBoxConverter.INSTANCE.convert(document);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) box));
|
||||
assertThat(shape).isEqualTo(box);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-858
|
||||
@@ -80,7 +83,7 @@ public class MongoConvertersUnitTests {
|
||||
Document document = GeoConverters.CircleToDocumentConverter.INSTANCE.convert(circle);
|
||||
Shape shape = GeoConverters.DocumentToCircleConverter.INSTANCE.convert(document);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) circle));
|
||||
assertThat(shape).isEqualTo(circle);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-858
|
||||
@@ -91,7 +94,7 @@ public class MongoConvertersUnitTests {
|
||||
Document document = GeoConverters.PolygonToDocumentConverter.INSTANCE.convert(polygon);
|
||||
Shape shape = GeoConverters.DocumentToPolygonConverter.INSTANCE.convert(document);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) polygon));
|
||||
assertThat(shape).isEqualTo(polygon);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-858
|
||||
@@ -102,7 +105,7 @@ public class MongoConvertersUnitTests {
|
||||
Document document = GeoConverters.SphereToDocumentConverter.INSTANCE.convert(sphere);
|
||||
org.springframework.data.geo.Shape shape = GeoConverters.DocumentToSphereConverter.INSTANCE.convert(document);
|
||||
|
||||
assertThat(shape, is((org.springframework.data.geo.Shape) sphere));
|
||||
assertThat(shape).isEqualTo(sphere);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-858
|
||||
@@ -113,36 +116,44 @@ public class MongoConvertersUnitTests {
|
||||
Document document = GeoConverters.PointToDocumentConverter.INSTANCE.convert(point);
|
||||
org.springframework.data.geo.Point converted = GeoConverters.DocumentToPointConverter.INSTANCE.convert(document);
|
||||
|
||||
assertThat(converted, is((org.springframework.data.geo.Point) point));
|
||||
assertThat(converted).isEqualTo(point);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1372
|
||||
public void convertsCurrencyToStringCorrectly() {
|
||||
assertThat(CurrencyToStringConverter.INSTANCE.convert(Currency.getInstance("USD")), is("USD"));
|
||||
assertThat(CurrencyToStringConverter.INSTANCE.convert(Currency.getInstance("USD"))).isEqualTo("USD");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1372
|
||||
public void convertsStringToCurrencyCorrectly() {
|
||||
assertThat(StringToCurrencyConverter.INSTANCE.convert("USD"), is(Currency.getInstance("USD")));
|
||||
assertThat(StringToCurrencyConverter.INSTANCE.convert("USD")).isEqualTo(Currency.getInstance("USD"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1416
|
||||
public void convertsAtomicLongToLongCorrectly() {
|
||||
assertThat(AtomicLongToLongConverter.INSTANCE.convert(new AtomicLong(100L)), is(100L));
|
||||
assertThat(AtomicLongToLongConverter.INSTANCE.convert(new AtomicLong(100L))).isEqualTo(100L);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1416
|
||||
public void convertsAtomicIntegerToIntegerCorrectly() {
|
||||
assertThat(AtomicIntegerToIntegerConverter.INSTANCE.convert(new AtomicInteger(100)), is(100));
|
||||
assertThat(AtomicIntegerToIntegerConverter.INSTANCE.convert(new AtomicInteger(100))).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1416
|
||||
public void convertsLongToAtomicLongCorrectly() {
|
||||
assertThat(LongToAtomicLongConverter.INSTANCE.convert(100L), is(instanceOf(AtomicLong.class)));
|
||||
assertThat(LongToAtomicLongConverter.INSTANCE.convert(100L)).isInstanceOf(AtomicLong.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1416
|
||||
public void convertsIntegerToAtomicIntegerCorrectly() {
|
||||
assertThat(IntegerToAtomicIntegerConverter.INSTANCE.convert(100), is(instanceOf(AtomicInteger.class)));
|
||||
assertThat(IntegerToAtomicIntegerConverter.INSTANCE.convert(100)).isInstanceOf(AtomicInteger.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2113
|
||||
public void convertsBsonTimestampToInstantCorrectly() {
|
||||
|
||||
assertThat(BsonTimestampToInstantConverter.INSTANCE.convert(new BsonTimestamp(6615900307735969796L)))
|
||||
.isCloseTo(Instant.ofEpochSecond(1540384327), new TemporalUnitLessThanOffset(100, ChronoUnit.MILLIS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ public class ChangeStreamTests {
|
||||
.append("user_name", "jellyBelly").append("age", 8).append("_class", User.class.getName()));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2012
|
||||
@Test // DATAMONGO-2012, DATAMONGO-2113
|
||||
public void resumeAtTimestampCorrectly() throws InterruptedException {
|
||||
|
||||
CollectingMessageListener<ChangeStreamDocument<Document>, User> messageListener1 = new CollectingMessageListener<>();
|
||||
@@ -415,6 +415,9 @@ public class ChangeStreamTests {
|
||||
awaitSubscription(subscription1);
|
||||
|
||||
template.save(jellyBelly);
|
||||
|
||||
Thread.sleep(1000); // cluster timestamp is in seconds, so we need to wait at least one.
|
||||
|
||||
template.save(sugarSplashy);
|
||||
|
||||
awaitMessages(messageListener1, 12);
|
||||
|
||||
@@ -25,10 +25,11 @@ import java.util.List;
|
||||
* Utilities for testing long running asnyc message retrieval.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class SubscriptionUtils {
|
||||
|
||||
static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(1);
|
||||
static final Duration DEFAULT_TIMEOUT = Duration.ofMillis(1500);
|
||||
|
||||
/**
|
||||
* Wait for {@link Subscription#isActive() to become active} but not longer than {@link #DEFAULT_TIMEOUT}.
|
||||
|
||||
@@ -34,7 +34,7 @@ Note that the domain type shown in the preceding example has a property named `i
|
||||
====
|
||||
[source]
|
||||
----
|
||||
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
|
||||
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {
|
||||
|
||||
// additional custom query methods go here
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ Note that the entity defined in the preceding example has a property named `id`
|
||||
====
|
||||
[source]
|
||||
----
|
||||
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, Long> {
|
||||
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
|
||||
|
||||
Flux<Person> findByFirstname(String firstname); <1>
|
||||
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 2.1.2.RELEASE (2018-10-29)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-2118 - Fix typo in repositories reference documentation.
|
||||
* DATAMONGO-2113 - ChangeStreamTasks incorrectly converts resumeAt Instants into BsonTimestamp.
|
||||
* DATAMONGO-2107 - Release 2.1.2 (Lovelace SR2).
|
||||
* DATAMONGO-2098 - Typo in MappingMongoConverterParser.
|
||||
|
||||
|
||||
Changes in version 1.10.16.RELEASE (2018-10-15)
|
||||
-----------------------------------------------
|
||||
* DATAMONGO-2096 - Aggregation.graphLookup.**.connectFrom(String) does not handle nested field.
|
||||
* DATAMONGO-2083 - Release 1.10.16 (Ingalls SR16).
|
||||
|
||||
|
||||
Changes in version 2.0.11.RELEASE (2018-10-15)
|
||||
----------------------------------------------
|
||||
* DATAMONGO-2101 - NoSuchMethodException: org.springframework.data.mongodb.core.geo.GeoJsonPoint.<init>().
|
||||
* DATAMONGO-2096 - Aggregation.graphLookup.**.connectFrom(String) does not handle nested field.
|
||||
* DATAMONGO-2087 - Typo in MongoRepository.
|
||||
* DATAMONGO-2086 - Kotlin Fluent API extensions do not allow projections with find queries.
|
||||
* DATAMONGO-2084 - Release 2.0.11 (Kay SR11).
|
||||
|
||||
|
||||
Changes in version 2.1.1.RELEASE (2018-10-15)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-2096 - Aggregation.graphLookup.**.connectFrom(String) does not handle nested field.
|
||||
* DATAMONGO-2094 - Release 2.1.1 (Lovelace SR1).
|
||||
|
||||
|
||||
Changes in version 2.1.0.RELEASE (2018-09-21)
|
||||
---------------------------------------------
|
||||
* DATAMONGO-2091 - Upgrade to MongoDB Java Driver 3.8.2 and Reactive Streams Driver 1.9.2.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 2.1 GA
|
||||
Spring Data MongoDB 2.1.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