Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
12b4aab834 | ||
|
|
db06756c8f | ||
|
|
b319b8a589 | ||
|
|
a516795759 | ||
|
|
bab08502a5 | ||
|
|
3e1f95bc94 | ||
|
|
5c153dc76e | ||
|
|
8f4e207d97 | ||
|
|
5000a40d72 | ||
|
|
fb59f49dae | ||
|
|
f3c1e014e9 | ||
|
|
f52cc3be1f | ||
|
|
1bda93858c | ||
|
|
1808970daf | ||
|
|
558fc28cce | ||
|
|
16bef54f11 | ||
|
|
d68a812e1b | ||
|
|
ccb9f111d9 | ||
|
|
f64b177c8f | ||
|
|
c0c7ba767f | ||
|
|
7639701f3f |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.6</version>
|
||||
<version>3.1.8</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.4.6</version>
|
||||
<version>2.4.8</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -26,7 +26,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>2.4.6</springdata.commons>
|
||||
<springdata.commons>2.4.8</springdata.commons>
|
||||
<mongo>4.1.2</mongo>
|
||||
<mongo.reactivestreams>${mongo}</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>3.1.6</version>
|
||||
<version>3.1.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.6</version>
|
||||
<version>3.1.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.1.6</version>
|
||||
<version>3.1.8</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -182,6 +183,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* any translation but rather reject a {@link Map} with keys containing dots causing the conversion for the entire
|
||||
* object to fail. If further customization of the translation is needed, have a look at
|
||||
* {@link #potentiallyEscapeMapKey(String)} as well as {@link #potentiallyUnescapeMapKey(String)}.
|
||||
* <p>
|
||||
* {@code mapKeyDotReplacement} is used as-is during replacement operations without further processing (i.e. regex or
|
||||
* normalization).
|
||||
*
|
||||
* @param mapKeyDotReplacement the mapKeyDotReplacement to set. Can be {@literal null}.
|
||||
*/
|
||||
@@ -900,7 +904,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
source));
|
||||
}
|
||||
|
||||
return source.replaceAll("\\.", mapKeyDotReplacement);
|
||||
return StringUtils.replace(source, ".", mapKeyDotReplacement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -928,7 +932,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
* @return
|
||||
*/
|
||||
protected String potentiallyUnescapeMapKey(String source) {
|
||||
return mapKeyDotReplacement == null ? source : source.replaceAll(mapKeyDotReplacement, "\\.");
|
||||
return mapKeyDotReplacement == null ? source : StringUtils.replace(source, mapKeyDotReplacement, ".");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1086,8 +1086,8 @@ public class QueryMapper {
|
||||
removePlaceholders(DOT_POSITIONAL_PATTERN, pathExpression));
|
||||
|
||||
if (sourceProperty != null && sourceProperty.getOwner().equals(entity)) {
|
||||
return mappingContext
|
||||
.getPersistentPropertyPath(PropertyPath.from(sourceProperty.getName(), entity.getTypeInformation()));
|
||||
return mappingContext.getPersistentPropertyPath(
|
||||
PropertyPath.from(Pattern.quote(sourceProperty.getName()), entity.getTypeInformation()));
|
||||
}
|
||||
|
||||
PropertyPath path = forName(rawPath);
|
||||
@@ -1146,6 +1146,13 @@ public class QueryMapper {
|
||||
return forName(path.substring(0, path.length() - 3) + "id");
|
||||
}
|
||||
|
||||
// Ok give it another try quoting
|
||||
try {
|
||||
return PropertyPath.from(Pattern.quote(path), entity.getTypeInformation());
|
||||
} catch (PropertyReferenceException | InvalidPersistentPropertyPath ex) {
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@ import static org.springframework.util.ObjectUtils.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -58,6 +60,7 @@ import com.mongodb.BasicDBList;
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Andreas Zink
|
||||
* @author Clément Petit
|
||||
*/
|
||||
public class Criteria implements CriteriaDefinition {
|
||||
|
||||
@@ -895,15 +898,15 @@ public class Criteria implements CriteriaDefinition {
|
||||
* @param right
|
||||
* @return
|
||||
*/
|
||||
private boolean isEqual(Object left, Object right) {
|
||||
private boolean isEqual(@Nullable Object left, @Nullable Object right) {
|
||||
|
||||
if (left == null) {
|
||||
return right == null;
|
||||
}
|
||||
|
||||
if (Pattern.class.isInstance(left)) {
|
||||
if (left instanceof Pattern) {
|
||||
|
||||
if (!Pattern.class.isInstance(right)) {
|
||||
if (!(right instanceof Pattern)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -914,6 +917,52 @@ public class Criteria implements CriteriaDefinition {
|
||||
&& leftPattern.flags() == rightPattern.flags();
|
||||
}
|
||||
|
||||
if (left instanceof Document) {
|
||||
|
||||
if (!(right instanceof Document)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Document leftDocument = (Document) left;
|
||||
Document rightDocument = (Document) right;
|
||||
Iterator<Entry<String, Object>> leftIterator = leftDocument.entrySet().iterator();
|
||||
Iterator<Entry<String, Object>> rightIterator = rightDocument.entrySet().iterator();
|
||||
|
||||
while (leftIterator.hasNext() && rightIterator.hasNext()) {
|
||||
|
||||
Map.Entry<String, Object> leftEntry = leftIterator.next();
|
||||
Map.Entry<String, Object> rightEntry = rightIterator.next();
|
||||
|
||||
if (!isEqual(leftEntry.getKey(), rightEntry.getKey())
|
||||
|| !isEqual(leftEntry.getValue(), rightEntry.getValue())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !leftIterator.hasNext() && !rightIterator.hasNext();
|
||||
}
|
||||
|
||||
if (Collection.class.isAssignableFrom(left.getClass())) {
|
||||
|
||||
if (!Collection.class.isAssignableFrom(right.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Collection<?> leftCollection = (Collection<?>) left;
|
||||
Collection<?> rightCollection = (Collection<?>) right;
|
||||
Iterator<?> leftIterator = leftCollection.iterator();
|
||||
Iterator<?> rightIterator = rightCollection.iterator();
|
||||
|
||||
while (leftIterator.hasNext() && rightIterator.hasNext()) {
|
||||
|
||||
if (!isEqual(leftIterator.next(), rightIterator.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !leftIterator.hasNext() && !rightIterator.hasNext();
|
||||
}
|
||||
|
||||
return ObjectUtils.nullSafeEquals(left, right);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.data.repository.query.QueryMethodEvaluationContextPro
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -163,9 +164,9 @@ abstract class AggregationUtils {
|
||||
* @throws IllegalArgumentException when none of the above rules is met.
|
||||
*/
|
||||
@Nullable
|
||||
static <T> T extractSimpleTypeResult(Document source, Class<T> targetType, MongoConverter converter) {
|
||||
static <T> T extractSimpleTypeResult(@Nullable Document source, Class<T> targetType, MongoConverter converter) {
|
||||
|
||||
if (source.isEmpty()) {
|
||||
if (ObjectUtils.isEmpty(source)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.mongodb.repository.support;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -215,7 +216,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
|
||||
Assert.notNull(ids, "The given Ids of entities not be null!");
|
||||
|
||||
return findAll(new Query(new Criteria(entityInformation.getIdAttribute())
|
||||
.in(Streamable.of(ids).stream().collect(StreamUtils.toUnmodifiableList()))));
|
||||
.in(toCollection(ids))));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -266,10 +267,10 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities not be null!");
|
||||
|
||||
List<S> list = Streamable.of(entities).stream().collect(StreamUtils.toUnmodifiableList());
|
||||
Collection<S> list = toCollection(entities);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return list;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return new ArrayList<>(mongoOperations.insertAll(list));
|
||||
@@ -374,6 +375,11 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
|
||||
return where(entityInformation.getIdAttribute()).is(id);
|
||||
}
|
||||
|
||||
private static <E> Collection<E> toCollection(Iterable<E> ids) {
|
||||
return ids instanceof Collection ? (Collection<E>) ids
|
||||
: StreamUtils.createStreamFromIterator(ids.iterator()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<T> findAll(@Nullable Query query) {
|
||||
|
||||
if (query == null) {
|
||||
|
||||
@@ -21,10 +21,11 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.domain.Example;
|
||||
@@ -47,6 +48,7 @@ import com.mongodb.client.result.DeleteResult;
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Ruben J Garcia
|
||||
* @author Clément Petit
|
||||
* @since 2.0
|
||||
*/
|
||||
public class SimpleReactiveMongoRepository<T, ID extends Serializable> implements ReactiveMongoRepository<T, ID> {
|
||||
@@ -173,7 +175,7 @@ public class SimpleReactiveMongoRepository<T, ID extends Serializable> implement
|
||||
Assert.notNull(ids, "The given Iterable of Id's must not be null!");
|
||||
|
||||
return findAll(new Query(new Criteria(entityInformation.getIdAttribute())
|
||||
.in(Streamable.of(ids).stream().collect(StreamUtils.toUnmodifiableList()))));
|
||||
.in(toCollection(ids))));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -274,9 +276,9 @@ public class SimpleReactiveMongoRepository<T, ID extends Serializable> implement
|
||||
|
||||
Assert.notNull(entities, "The given Iterable of entities must not be null!");
|
||||
|
||||
List<S> source = Streamable.of(entities).stream().collect(StreamUtils.toUnmodifiableList());
|
||||
Collection<S> source = toCollection(entities);
|
||||
|
||||
return source.isEmpty() ? Flux.empty() : Flux.from(mongoOperations.insertAll(source));
|
||||
return source.isEmpty() ? Flux.empty() : mongoOperations.insertAll(source);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -333,8 +335,8 @@ public class SimpleReactiveMongoRepository<T, ID extends Serializable> implement
|
||||
Assert.notNull(entityStream, "The given Publisher of entities must not be null!");
|
||||
|
||||
return Flux.from(entityStream).flatMap(entity -> entityInformation.isNew(entity) ? //
|
||||
mongoOperations.insert(entity, entityInformation.getCollectionName()).then(Mono.just(entity)) : //
|
||||
mongoOperations.save(entity, entityInformation.getCollectionName()).then(Mono.just(entity)));
|
||||
mongoOperations.insert(entity, entityInformation.getCollectionName()) : //
|
||||
mongoOperations.save(entity, entityInformation.getCollectionName()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -436,8 +438,12 @@ public class SimpleReactiveMongoRepository<T, ID extends Serializable> implement
|
||||
return where(entityInformation.getIdAttribute()).is(id);
|
||||
}
|
||||
|
||||
private Flux<T> findAll(Query query) {
|
||||
private static <E> Collection<E> toCollection(Iterable<E> ids) {
|
||||
return ids instanceof Collection ? (Collection<E>) ids
|
||||
: StreamUtils.createStreamFromIterator(ids.iterator()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Flux<T> findAll(Query query) {
|
||||
return mongoOperations.find(query, entityInformation.getJavaType(), entityInformation.getCollectionName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,7 +781,8 @@ public class QueryMapperUnitTests {
|
||||
Query query = query(byExample(probe).and("listOfItems").exists(true));
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Foo.class));
|
||||
|
||||
assertThat(document).containsEntry("embedded\\._id", "conflux").containsEntry("my_items", new org.bson.Document("$exists", true));
|
||||
assertThat(document).containsEntry("embedded\\._id", "conflux").containsEntry("my_items",
|
||||
new org.bson.Document("$exists", true));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1988
|
||||
@@ -1011,6 +1012,76 @@ public class QueryMapperUnitTests {
|
||||
assertThat(target).isEqualTo(org.bson.Document.parse("{\"$text\" : { \"$search\" : \"test\" }}"));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document)
|
||||
.isEqualTo(new org.bson.Document("fieldname_with_underscores", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesMappedFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("renamed_fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document).isEqualTo(new org.bson.Document("renamed", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesSimpleNestedFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("simple.fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document)
|
||||
.isEqualTo(new org.bson.Document("simple.fieldname_with_underscores", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesSimpleNestedMappedFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("simple.renamed_fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document).isEqualTo(new org.bson.Document("simple.renamed", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesFieldNameWithUnderscoreOnNestedFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("double_underscore.fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document).isEqualTo(
|
||||
new org.bson.Document("double_underscore.fieldname_with_underscores", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
@Test // GH-3601
|
||||
void resolvesFieldNameWithUnderscoreOnNestedMappedFieldnameWithUnderscoresCorrectly() {
|
||||
|
||||
Query query = query(where("double_underscore.renamed_fieldname_with_underscores").exists(true));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(WrapperAroundWithPropertyUsingUnderscoreInName.class));
|
||||
|
||||
assertThat(document)
|
||||
.isEqualTo(new org.bson.Document("double_underscore.renamed", new org.bson.Document("$exists", true)));
|
||||
}
|
||||
|
||||
class WithDeepArrayNesting {
|
||||
|
||||
List<WithNestedArray> level0;
|
||||
@@ -1194,4 +1265,17 @@ public class QueryMapperUnitTests {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static class WrapperAroundWithPropertyUsingUnderscoreInName {
|
||||
|
||||
WithPropertyUsingUnderscoreInName simple;
|
||||
WithPropertyUsingUnderscoreInName double_underscore;
|
||||
}
|
||||
|
||||
static class WithPropertyUsingUnderscoreInName {
|
||||
|
||||
String fieldname_with_underscores;
|
||||
|
||||
@Field("renamed") String renamed_fieldname_with_underscores;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.springframework.data.mongodb.core.schema.MongoJsonSchema;
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Andreas Zink
|
||||
* @author Clément Petit
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class CriteriaUnitTests {
|
||||
|
||||
@@ -310,9 +312,72 @@ public class CriteriaUnitTests {
|
||||
@Test // DATAMONGO-2002
|
||||
public void shouldEqualForSamePattern() {
|
||||
|
||||
Criteria left = new Criteria("field").regex("foo");
|
||||
Criteria right = new Criteria("field").regex("foo");
|
||||
|
||||
assertThat(left).isEqualTo(right);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2002
|
||||
public void shouldEqualForDocument() {
|
||||
|
||||
assertThat(new Criteria("field").is(new Document("one", 1).append("two", "two").append("null", null)))
|
||||
.isEqualTo(new Criteria("field").is(new Document("one", 1).append("two", "two").append("null", null)));
|
||||
|
||||
assertThat(new Criteria("field").is(new Document("one", 1).append("two", "two").append("null", null)))
|
||||
.isNotEqualTo(new Criteria("field").is(new Document("one", 1).append("two", "two")));
|
||||
|
||||
assertThat(new Criteria("field").is(new Document("one", 1).append("two", "two")))
|
||||
.isNotEqualTo(new Criteria("field").is(new Document("one", 1).append("two", "two").append("null", null)));
|
||||
|
||||
assertThat(new Criteria("field").is(new Document("one", 1).append("null", null).append("two", "two")))
|
||||
.isNotEqualTo(new Criteria("field").is(new Document("one", 1).append("two", "two").append("null", null)));
|
||||
|
||||
assertThat(new Criteria("field").is(new Document())).isNotEqualTo(new Criteria("field").is("foo"));
|
||||
assertThat(new Criteria("field").is("foo")).isNotEqualTo(new Criteria("field").is(new Document()));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2002
|
||||
public void shouldEqualForCollection() {
|
||||
|
||||
assertThat(new Criteria("field").is(Arrays.asList("foo", "bar")))
|
||||
.isEqualTo(new Criteria("field").is(Arrays.asList("foo", "bar")));
|
||||
|
||||
assertThat(new Criteria("field").is(Arrays.asList("foo", 1)))
|
||||
.isNotEqualTo(new Criteria("field").is(Arrays.asList("foo", "bar")));
|
||||
|
||||
assertThat(new Criteria("field").is(Collections.singletonList("foo")))
|
||||
.isNotEqualTo(new Criteria("field").is(Arrays.asList("foo", "bar")));
|
||||
|
||||
assertThat(new Criteria("field").is(Arrays.asList("foo", "bar")))
|
||||
.isNotEqualTo(new Criteria("field").is(Collections.singletonList("foo")));
|
||||
|
||||
assertThat(new Criteria("field").is(Arrays.asList("foo", "bar"))).isNotEqualTo(new Criteria("field").is("foo"));
|
||||
|
||||
assertThat(new Criteria("field").is("foo")).isNotEqualTo(new Criteria("field").is(Arrays.asList("foo", "bar")));
|
||||
}
|
||||
|
||||
@Test // GH-3414
|
||||
public void shouldEqualForSamePatternAndFlags() {
|
||||
|
||||
Criteria left = new Criteria("field").regex("foo", "iu");
|
||||
Criteria right = new Criteria("field").regex("foo");
|
||||
|
||||
assertThat(left).isNotEqualTo(right);
|
||||
}
|
||||
|
||||
@Test // GH-3414
|
||||
public void shouldEqualForNestedPattern() {
|
||||
|
||||
Criteria left = new Criteria("a").orOperator(
|
||||
new Criteria("foo").regex("value", "i"),
|
||||
new Criteria("bar").regex("value")
|
||||
);
|
||||
Criteria right = new Criteria("a").orOperator(
|
||||
new Criteria("foo").regex("value", "i"),
|
||||
new Criteria("bar").regex("value")
|
||||
);
|
||||
|
||||
assertThat(left).isEqualTo(right);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,19 @@ import static org.springframework.data.domain.ExampleMatcher.*;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
@@ -44,10 +48,9 @@ import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
|
||||
import org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactory;
|
||||
import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.ReactiveQueryMethodEvaluationContextProvider;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
@@ -56,19 +59,22 @@ import org.springframework.util.ClassUtils;
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @author Ruben J Garcia
|
||||
* @author Clément Petit
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration("classpath:reactive-infrastructure.xml")
|
||||
public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware, BeanFactoryAware {
|
||||
|
||||
@Autowired private ReactiveMongoTemplate template;
|
||||
|
||||
ReactiveMongoRepositoryFactory factory;
|
||||
ClassLoader classLoader;
|
||||
BeanFactory beanFactory;
|
||||
ReactivePersonRepostitory repository;
|
||||
private ReactiveMongoRepositoryFactory factory;
|
||||
private ClassLoader classLoader;
|
||||
private BeanFactory beanFactory;
|
||||
private ReactivePersonRepository repository;
|
||||
private ReactiveImmutablePersonRepository immutableRepository;
|
||||
|
||||
private ReactivePerson dave, oliver, carter, boyd, stefan, leroi, alicia;
|
||||
private ImmutableReactivePerson keith, james, mariah;
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
@@ -80,8 +86,8 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
|
||||
factory = new ReactiveMongoRepositoryFactory(template);
|
||||
factory.setRepositoryBaseClass(SimpleReactiveMongoRepository.class);
|
||||
@@ -89,9 +95,11 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
factory.setBeanFactory(beanFactory);
|
||||
factory.setEvaluationContextProvider(ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
|
||||
repository = factory.getRepository(ReactivePersonRepostitory.class);
|
||||
repository = factory.getRepository(ReactivePersonRepository.class);
|
||||
immutableRepository = factory.getRepository(ReactiveImmutablePersonRepository.class);
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
immutableRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
dave = new ReactivePerson("Dave", "Matthews", 42);
|
||||
oliver = new ReactivePerson("Oliver August", "Matthews", 4);
|
||||
@@ -100,6 +108,9 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
stefan = new ReactivePerson("Stefan", "Lessard", 34);
|
||||
leroi = new ReactivePerson("Leroi", "Moore", 41);
|
||||
alicia = new ReactivePerson("Alicia", "Keys", 30);
|
||||
keith = new ImmutableReactivePerson(null, "Keith", "Urban", 53);
|
||||
james = new ImmutableReactivePerson(null, "James", "Arthur", 33);
|
||||
mariah = new ImmutableReactivePerson(null, "Mariah", "Carey", 51);
|
||||
|
||||
repository.saveAll(Arrays.asList(oliver, dave, carter, boyd, stefan, leroi, alicia)).as(StepVerifier::create) //
|
||||
.expectNextCount(7) //
|
||||
@@ -107,78 +118,78 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void existsByIdShouldReturnTrueForExistingObject() {
|
||||
void existsByIdShouldReturnTrueForExistingObject() {
|
||||
repository.existsById(dave.id).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void existsByIdShouldReturnFalseForAbsentObject() {
|
||||
void existsByIdShouldReturnFalseForAbsentObject() {
|
||||
repository.existsById("unknown").as(StepVerifier::create).expectNext(false).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void existsByMonoOfIdShouldReturnTrueForExistingObject() {
|
||||
void existsByMonoOfIdShouldReturnTrueForExistingObject() {
|
||||
repository.existsById(Mono.just(dave.id)).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1712
|
||||
public void existsByFluxOfIdShouldReturnTrueForExistingObject() {
|
||||
void existsByFluxOfIdShouldReturnTrueForExistingObject() {
|
||||
repository.existsById(Flux.just(dave.id, oliver.id)).as(StepVerifier::create).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void existsByEmptyMonoOfIdShouldReturnEmptyMono() {
|
||||
void existsByEmptyMonoOfIdShouldReturnEmptyMono() {
|
||||
repository.existsById(Mono.empty()).as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findByIdShouldReturnObject() {
|
||||
void findByIdShouldReturnObject() {
|
||||
repository.findById(dave.id).as(StepVerifier::create).expectNext(dave).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findByIdShouldCompleteWithoutValueForAbsentObject() {
|
||||
void findByIdShouldCompleteWithoutValueForAbsentObject() {
|
||||
repository.findById("unknown").as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findByIdByMonoOfIdShouldReturnTrueForExistingObject() {
|
||||
void findByIdByMonoOfIdShouldReturnTrueForExistingObject() {
|
||||
repository.findById(Mono.just(dave.id)).as(StepVerifier::create).expectNext(dave).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1712
|
||||
public void findByIdByFluxOfIdShouldReturnTrueForExistingObject() {
|
||||
void findByIdByFluxOfIdShouldReturnTrueForExistingObject() {
|
||||
repository.findById(Flux.just(dave.id, oliver.id)).as(StepVerifier::create).expectNext(dave).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findByIdByEmptyMonoOfIdShouldReturnEmptyMono() {
|
||||
void findByIdByEmptyMonoOfIdShouldReturnEmptyMono() {
|
||||
repository.findById(Mono.empty()).as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findAllShouldReturnAllResults() {
|
||||
void findAllShouldReturnAllResults() {
|
||||
repository.findAll().as(StepVerifier::create).expectNextCount(7).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findAllByIterableOfIdShouldReturnResults() {
|
||||
void findAllByIterableOfIdShouldReturnResults() {
|
||||
repository.findAllById(Arrays.asList(dave.id, boyd.id)).as(StepVerifier::create).expectNextCount(2)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findAllByPublisherOfIdShouldReturnResults() {
|
||||
void findAllByPublisherOfIdShouldReturnResults() {
|
||||
repository.findAllById(Flux.just(dave.id, boyd.id)).as(StepVerifier::create).expectNextCount(2).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findAllByEmptyPublisherOfIdShouldReturnResults() {
|
||||
void findAllByEmptyPublisherOfIdShouldReturnResults() {
|
||||
repository.findAllById(Flux.empty()).as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void findAllWithSortShouldReturnResults() {
|
||||
void findAllWithSortShouldReturnResults() {
|
||||
|
||||
repository.findAll(Sort.by(new Order(Direction.ASC, "age"))).as(StepVerifier::create) //
|
||||
.expectNextCount(7) //
|
||||
@@ -186,12 +197,12 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void countShouldReturnNumberOfRecords() {
|
||||
void countShouldReturnNumberOfRecords() {
|
||||
repository.count().as(StepVerifier::create).expectNext(7L).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void insertEntityShouldInsertEntity() {
|
||||
void insertEntityShouldInsertEntity() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -203,7 +214,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void insertShouldDeferredWrite() {
|
||||
void insertShouldDeferredWrite() {
|
||||
|
||||
ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36);
|
||||
|
||||
@@ -213,7 +224,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void insertIterableOfEntitiesShouldInsertEntity() {
|
||||
void insertIterableOfEntitiesShouldInsertEntity() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -231,7 +242,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void insertPublisherOfEntitiesShouldInsertEntity() {
|
||||
void insertPublisherOfEntitiesShouldInsertEntity() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -247,7 +258,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void saveEntityShouldUpdateExistingEntity() {
|
||||
void saveEntityShouldUpdateExistingEntity() {
|
||||
|
||||
dave.setFirstname("Hello, Dave");
|
||||
dave.setLastname("Bowman");
|
||||
@@ -264,7 +275,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void saveEntityShouldInsertNewEntity() {
|
||||
void saveEntityShouldInsertNewEntity() {
|
||||
|
||||
ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36);
|
||||
|
||||
@@ -278,7 +289,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void saveIterableOfNewEntitiesShouldInsertEntity() {
|
||||
void saveIterableOfNewEntitiesShouldInsertEntity() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -294,7 +305,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void saveIterableOfMixedEntitiesShouldInsertEntity() {
|
||||
void saveIterableOfMixedEntitiesShouldInsertEntity() {
|
||||
|
||||
ReactivePerson person = new ReactivePerson("Homer", "Simpson", 36);
|
||||
|
||||
@@ -310,7 +321,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void savePublisherOfEntitiesShouldInsertEntity() {
|
||||
void savePublisherOfEntitiesShouldInsertEntity() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -325,8 +336,20 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
assertThat(boyd.getId()).isNotNull();
|
||||
}
|
||||
|
||||
@Test // GH-3609
|
||||
void savePublisherOfImmutableEntitiesShouldInsertEntity() {
|
||||
|
||||
immutableRepository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
immutableRepository.saveAll(Flux.just(keith)).as(StepVerifier::create) //
|
||||
.consumeNextWith(actual -> {
|
||||
assertThat(actual.id).isNotNull();
|
||||
}) //
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void deleteAllShouldRemoveEntities() {
|
||||
void deleteAllShouldRemoveEntities() {
|
||||
|
||||
repository.deleteAll().as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -334,7 +357,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void deleteByIdShouldRemoveEntity() {
|
||||
void deleteByIdShouldRemoveEntity() {
|
||||
|
||||
repository.deleteById(dave.id).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -342,7 +365,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1712
|
||||
public void deleteByIdUsingMonoShouldRemoveEntity() {
|
||||
void deleteByIdUsingMonoShouldRemoveEntity() {
|
||||
|
||||
repository.deleteById(Mono.just(dave.id)).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -350,7 +373,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1712
|
||||
public void deleteByIdUsingFluxShouldRemoveEntity() {
|
||||
void deleteByIdUsingFluxShouldRemoveEntity() {
|
||||
|
||||
repository.deleteById(Flux.just(dave.id, oliver.id)).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -359,7 +382,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void deleteShouldRemoveEntity() {
|
||||
void deleteShouldRemoveEntity() {
|
||||
|
||||
repository.delete(dave).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -368,7 +391,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void deleteIterableOfEntitiesShouldRemoveEntities() {
|
||||
void deleteIterableOfEntitiesShouldRemoveEntities() {
|
||||
|
||||
repository.deleteAll(Arrays.asList(dave, boyd)).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -378,7 +401,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1444
|
||||
public void deletePublisherOfEntitiesShouldRemoveEntities() {
|
||||
void deletePublisherOfEntitiesShouldRemoveEntities() {
|
||||
|
||||
repository.deleteAll(Flux.just(dave, boyd)).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
@@ -388,7 +411,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void findOneByExampleShouldReturnObject() {
|
||||
void findOneByExampleShouldReturnObject() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(dave);
|
||||
|
||||
@@ -396,7 +419,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void findAllByExampleShouldReturnObjects() {
|
||||
void findAllByExampleShouldReturnObjects() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(dave, matching().withIgnorePaths("id", "age", "firstname"));
|
||||
|
||||
@@ -404,7 +427,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void findAllByExampleAndSortShouldReturnObjects() {
|
||||
void findAllByExampleAndSortShouldReturnObjects() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(dave, matching().withIgnorePaths("id", "age", "firstname"));
|
||||
|
||||
@@ -413,7 +436,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void countByExampleShouldCountObjects() {
|
||||
void countByExampleShouldCountObjects() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(dave, matching().withIgnorePaths("id", "age", "firstname"));
|
||||
|
||||
@@ -421,7 +444,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void existsByExampleShouldReturnExisting() {
|
||||
void existsByExampleShouldReturnExisting() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(dave, matching().withIgnorePaths("id", "age", "firstname"));
|
||||
|
||||
@@ -429,7 +452,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void existsByExampleShouldReturnNonExisting() {
|
||||
void existsByExampleShouldReturnNonExisting() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(new ReactivePerson("foo", "bar", -1));
|
||||
|
||||
@@ -437,7 +460,7 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1619
|
||||
public void findOneShouldEmitIncorrectResultSizeDataAccessExceptionWhenMoreThanOneElementFound() {
|
||||
void findOneShouldEmitIncorrectResultSizeDataAccessExceptionWhenMoreThanOneElementFound() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(new ReactivePerson(null, "Matthews", -1),
|
||||
matching().withIgnorePaths("age"));
|
||||
@@ -446,19 +469,23 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1907
|
||||
public void findOneByExampleWithoutResultShouldCompleteEmpty() {
|
||||
void findOneByExampleWithoutResultShouldCompleteEmpty() {
|
||||
|
||||
Example<ReactivePerson> example = Example.of(new ReactivePerson("foo", "bar", -1));
|
||||
|
||||
repository.findOne(example).as(StepVerifier::create).verifyComplete();
|
||||
}
|
||||
|
||||
interface ReactivePersonRepostitory extends ReactiveMongoRepository<ReactivePerson, String> {
|
||||
interface ReactivePersonRepository extends ReactiveMongoRepository<ReactivePerson, String> {
|
||||
|
||||
Flux<ReactivePerson> findByLastname(String lastname);
|
||||
|
||||
}
|
||||
|
||||
interface ReactiveImmutablePersonRepository extends ReactiveMongoRepository<ImmutableReactivePerson, String> {
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
static class ReactivePerson {
|
||||
@@ -469,11 +496,30 @@ public class SimpleReactiveMongoRepositoryTests implements BeanClassLoaderAware,
|
||||
String lastname;
|
||||
int age;
|
||||
|
||||
public ReactivePerson(String firstname, String lastname, int age) {
|
||||
ReactivePerson(String firstname, String lastname, int age) {
|
||||
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
|
||||
@With
|
||||
@Value
|
||||
static class ImmutableReactivePerson {
|
||||
|
||||
@Id String id;
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
int age;
|
||||
|
||||
ImmutableReactivePerson(@Nullable String id, String firstname, String lastname, int age) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -159,6 +159,14 @@ public class StringBasedAggregationUnitTests {
|
||||
assertThat(executeAggregation("returnCollection").result).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test // GH-3623
|
||||
public void returnNullWhenSingleResultIsNotPresent() {
|
||||
|
||||
when(aggregationResults.getMappedResults()).thenReturn(Collections.emptyList());
|
||||
|
||||
assertThat(executeAggregation("simpleReturnType").result).isNull();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2153
|
||||
public void returnRawResultType() {
|
||||
assertThat(executeAggregation("returnRawResultType").result).isEqualTo(aggregationResults);
|
||||
@@ -312,6 +320,9 @@ public class StringBasedAggregationUnitTests {
|
||||
|
||||
@Aggregation(RAW_GROUP_BY_LASTNAME_STRING)
|
||||
Page<Person> invalidPageReturnType(Pageable page);
|
||||
|
||||
@Aggregation(RAW_GROUP_BY_LASTNAME_STRING)
|
||||
String simpleReturnType();
|
||||
}
|
||||
|
||||
static class PersonAggregate {
|
||||
|
||||
@@ -1,6 +1,53 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 3.1.8 (2021-04-14)
|
||||
-------------------------------------
|
||||
* #3623 - `@Aggregation` repository query method causes `NullPointerException` when the result is empty.
|
||||
* #3601 - Criteria object not allowing to use field names with underscore in them.
|
||||
* #3414 - Criteria or toEquals fail if contains regex [DATAMONGO-2559].
|
||||
|
||||
|
||||
Changes in version 3.0.9.RELEASE (2021-04-14)
|
||||
---------------------------------------------
|
||||
* #3623 - `@Aggregation` repository query method causes `NullPointerException` when the result is empty.
|
||||
* #3609 - SimpleReactiveMongoRepository#saveAll does not populate @Id property if it is immutable.
|
||||
* #3414 - Criteria or toEquals fail if contains regex [DATAMONGO-2559].
|
||||
|
||||
|
||||
Changes in version 3.1.7 (2021-03-31)
|
||||
-------------------------------------
|
||||
* #3613 - Use StringUtils.replace(…) instead of String.replaceAll(…) for mapKeyDotReplacement.
|
||||
* #3609 - SimpleReactiveMongoRepository#saveAll does not populate @Id property if it is immutable.
|
||||
|
||||
|
||||
Changes in version 3.2.0-RC1 (2021-03-31)
|
||||
-----------------------------------------
|
||||
* #3613 - Use StringUtils.replace(…) instead of String.replaceAll(…) for mapKeyDotReplacement.
|
||||
* #3609 - SimpleReactiveMongoRepository#saveAll does not populate @Id property if it is immutable.
|
||||
* #3600 - Rename Embedded annotation -> Unwrapped.
|
||||
* #3583 - Support aggregation expression on fields projection.
|
||||
|
||||
|
||||
Changes in version 3.2.0-M5 (2021-03-17)
|
||||
----------------------------------------
|
||||
* #3592 - Remove @Persistent from entity-scan include filters.
|
||||
* #3590 - Embedded sharding keys are not correctly picked up from the shardKeySource Document.
|
||||
* #3580 - Fix CustomConverter conversion lookup.
|
||||
* #3579 - Upgrade to MongoDB Java Drivers 4.2.2.
|
||||
* #3575 - Introduce ConversionContext and clean up MappingMongoConverter.
|
||||
* #3573 - Json Schema section appears twice in reference documentation.
|
||||
* #3571 - Introduce ConversionContext and clean up MappingMongoConverter.
|
||||
* #3570 - Incorrect class casting cause ClassCastException when save java.util.Collection using MongoTemplate.
|
||||
* #3568 - MongoSocketWriteException may be translated into DataAccessResourceFailureException.
|
||||
* #3566 - Couldn't find PersistentEntity for type java.lang.Object when updating a field with suffix "class".
|
||||
* #3552 - UpdateMapper drops numeric keys in Maps.
|
||||
* #3395 - Derived findBy…IgnoreCaseIn query doesn't return expected results [DATAMONGO-2540].
|
||||
* #3286 - Add possibility to use Collection<Criteria> as parameter in and/or/nor operators [DATAMONGO-2428].
|
||||
* #2911 - ensureNotIterable in MongoTemplate only checks for array type [DATAMONGO-2044].
|
||||
* #590 - DATAMONGO-2044 make ensureNotIterable actually check if object is iterable.
|
||||
|
||||
|
||||
Changes in version 3.1.6 (2021-03-17)
|
||||
-------------------------------------
|
||||
* #3592 - Remove @Persistent from entity-scan include filters.
|
||||
@@ -3363,6 +3410,11 @@ Repository
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 3.1.6 (2020.0.6)
|
||||
Spring Data MongoDB 3.1.8 (2020.0.8)
|
||||
Copyright (c) [2010-2019] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -26,3 +26,5 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user