Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7385262c47 | ||
|
|
259938588a | ||
|
|
a1b4e3fc55 | ||
|
|
76479820bc | ||
|
|
c47bbc4a20 | ||
|
|
74791d0bca | ||
|
|
f4d2287011 | ||
|
|
ab6ba194c1 | ||
|
|
595a346705 | ||
|
|
08c5e5a810 | ||
|
|
f987217c3c | ||
|
|
92a22978c2 | ||
|
|
2e2e076b5b | ||
|
|
0c50d97887 | ||
|
|
c10d4b6af0 | ||
|
|
6644ac6875 | ||
|
|
708def0df1 | ||
|
|
889e5d52bb |
6
pom.xml
6
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.4</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.5.2</version>
|
||||
<version>2.5.4</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
@@ -26,7 +26,7 @@
|
||||
<properties>
|
||||
<project.type>multi</project.type>
|
||||
<dist.id>spring-data-mongodb</dist.id>
|
||||
<springdata.commons>2.5.2</springdata.commons>
|
||||
<springdata.commons>2.5.4</springdata.commons>
|
||||
<mongo>4.2.3</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.2.2</version>
|
||||
<version>3.2.4</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.4</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-mongodb-parent</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<version>3.2.4</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -1040,7 +1040,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private Object getPotentiallyConvertedSimpleRead(Object value, @Nullable Class<?> target) {
|
||||
|
||||
if (target == null || ClassUtils.isAssignableValue(target, value)) {
|
||||
if (target == null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -1048,6 +1048,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
return doConvert(value, target);
|
||||
}
|
||||
|
||||
if (ClassUtils.isAssignableValue(target, value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (Enum.class.isAssignableFrom(target)) {
|
||||
return Enum.valueOf((Class<Enum>) target, value.toString());
|
||||
}
|
||||
@@ -1136,7 +1140,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
for (Object element : source) {
|
||||
items.add(context.convert(element, componentType));
|
||||
items.add(element != null ? context.convert(element, componentType) : element);
|
||||
}
|
||||
|
||||
return getPotentiallyConvertedSimpleRead(items, targetType.getType());
|
||||
@@ -1880,6 +1884,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends Object> S convert(Object source, TypeInformation<? extends S> typeHint) {
|
||||
|
||||
Assert.notNull(source, "Source must not be null");
|
||||
Assert.notNull(typeHint, "TypeInformation must not be null");
|
||||
|
||||
if (conversions.hasCustomReadTarget(source.getClass(), typeHint.getType())) {
|
||||
@@ -1902,7 +1907,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
}
|
||||
|
||||
if (typeHint.isMap()) {
|
||||
return (S) mapConverter.convert(this, (Bson) source, typeHint);
|
||||
|
||||
if(ClassUtils.isAssignable(Document.class, typeHint.getType())) {
|
||||
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
|
||||
}
|
||||
|
||||
if (BsonUtils.supportsBson(source)) {
|
||||
return (S) mapConverter.convert(this, BsonUtils.asBson(source), typeHint);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Expected map like structure but found %s", source.getClass()));
|
||||
}
|
||||
|
||||
if (source instanceof DBRef) {
|
||||
@@ -1914,8 +1928,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
String.format(INCOMPATIBLE_TYPES, source, BasicDBList.class, typeHint.getType(), getPath()));
|
||||
}
|
||||
|
||||
if (source instanceof Bson) {
|
||||
return (S) documentConverter.convert(this, (Bson) source, typeHint);
|
||||
if (BsonUtils.supportsBson(source)) {
|
||||
return (S) documentConverter.convert(this, BsonUtils.asBson(source), typeHint);
|
||||
}
|
||||
|
||||
return (S) elementConverter.convert(source, typeHint);
|
||||
|
||||
@@ -68,6 +68,7 @@ import com.mongodb.DBRef;
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author David Julia
|
||||
*/
|
||||
public class QueryMapper {
|
||||
|
||||
@@ -1361,12 +1362,17 @@ public class QueryMapper {
|
||||
static class KeyMapper {
|
||||
|
||||
private final Iterator<String> iterator;
|
||||
private int currentIndex;
|
||||
private String currentPropertyRoot;
|
||||
private final List<String> pathParts;
|
||||
|
||||
public KeyMapper(String key,
|
||||
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
|
||||
|
||||
this.iterator = Arrays.asList(key.split("\\.")).iterator();
|
||||
this.iterator.next();
|
||||
this.pathParts = Arrays.asList(key.split("\\."));
|
||||
this.iterator = pathParts.iterator();
|
||||
this.currentPropertyRoot = iterator.next();
|
||||
this.currentIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1378,21 +1384,31 @@ public class QueryMapper {
|
||||
protected String mapPropertyName(MongoPersistentProperty property) {
|
||||
|
||||
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
|
||||
|
||||
boolean inspect = iterator.hasNext();
|
||||
|
||||
while (inspect) {
|
||||
|
||||
String partial = iterator.next();
|
||||
currentIndex++;
|
||||
|
||||
boolean isPositional = isPositionalParameter(partial) && property.isCollectionLike() ;
|
||||
if(property.isMap() && currentPropertyRoot.equals(partial) && iterator.hasNext()){
|
||||
partial = iterator.next();
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
if (isPositional || property.isMap()) {
|
||||
if (isPositional || property.isMap() && !currentPropertyRoot.equals(partial)) {
|
||||
mappedName.append(".").append(partial);
|
||||
}
|
||||
|
||||
inspect = isPositional && iterator.hasNext();
|
||||
}
|
||||
|
||||
if(currentIndex + 1 < pathParts.size()) {
|
||||
currentIndex++;
|
||||
currentPropertyRoot = pathParts.get(currentIndex);
|
||||
}
|
||||
return mappedName.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,11 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @author Rogério Meneguelli Gatto
|
||||
* @since 3.2
|
||||
*/
|
||||
class UnwrapEntityContext {
|
||||
@@ -30,4 +33,32 @@ class UnwrapEntityContext {
|
||||
public MongoPersistentProperty getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UnwrapEntityContext that = (UnwrapEntityContext) obj;
|
||||
return ObjectUtils.nullSafeEquals(property, that.property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(property);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,13 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentPropertyAccessor;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Unwrapped variant of {@link MongoPersistentProperty}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Rogério Meneguelli Gatto
|
||||
* @since 3.2
|
||||
* @see Unwrapped
|
||||
*/
|
||||
@@ -304,4 +306,38 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
|
||||
public <T> PersistentPropertyAccessor<T> getAccessorForOwner(T owner) {
|
||||
return delegate.getAccessorForOwner(owner);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UnwrappedMongoPersistentProperty that = (UnwrappedMongoPersistentProperty) obj;
|
||||
if (!ObjectUtils.nullSafeEquals(delegate, that.delegate)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(context, that.context);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = ObjectUtils.nullSafeHashCode(delegate);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(context);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +212,10 @@ public class QuerydslMongoPredicateExecutor<T> extends QuerydslPredicateExecutor
|
||||
*/
|
||||
private SpringDataMongodbQuery<T> applyPagination(SpringDataMongodbQuery<T> query, Pageable pageable) {
|
||||
|
||||
if (pageable.isUnpaged()) {
|
||||
return query;
|
||||
}
|
||||
|
||||
query = query.offset(pageable.getOffset()).limit(pageable.getPageSize());
|
||||
return applySorting(query, pageable.getSort());
|
||||
}
|
||||
|
||||
@@ -488,6 +488,49 @@ public class BsonUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given source object as {@link Bson}, i.e. {@link Document}s and maps as is or throw
|
||||
* {@link IllegalArgumentException}.
|
||||
*
|
||||
* @param source
|
||||
* @return the converted/casted source object.
|
||||
* @throws IllegalArgumentException if {@code source} cannot be converted/cast to {@link Bson}.
|
||||
* @since 3.2.3
|
||||
* @see #supportsBson(Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Bson asBson(Object source) {
|
||||
|
||||
if (source instanceof Document) {
|
||||
return (Document) source;
|
||||
}
|
||||
|
||||
if (source instanceof BasicDBObject) {
|
||||
return (BasicDBObject) source;
|
||||
}
|
||||
|
||||
if (source instanceof DBObject) {
|
||||
return new Document(((DBObject) source).toMap());
|
||||
}
|
||||
|
||||
if (source instanceof Map) {
|
||||
return new Document((Map<String, Object>) source);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException(String.format("Cannot convert %s to Bson", source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given source can be used/converted as {@link Bson}.
|
||||
*
|
||||
* @param source
|
||||
* @return {@literal true} if the given source can be converted to {@link Bson}.
|
||||
* @since 3.2.3
|
||||
*/
|
||||
public static boolean supportsBson(Object source) {
|
||||
return source instanceof DBObject || source instanceof Map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a
|
||||
* {@link Collection} already, will convert an array into a {@link Collection} or simply create a single element
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
|
||||
import org.bson.types.Binary;
|
||||
import org.bson.types.Code;
|
||||
import org.bson.types.Decimal128;
|
||||
import org.bson.types.ObjectId;
|
||||
@@ -933,10 +934,11 @@ class MappingMongoConverterUnitTests {
|
||||
assertThat(readResult.iterator().next()).isInstanceOf(Address.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-402
|
||||
@Test // DATAMONGO-402, GH-3702
|
||||
void readsMemberClassCorrectly() {
|
||||
|
||||
org.bson.Document document = new org.bson.Document("inner", new org.bson.Document("value", "FOO!"));
|
||||
org.bson.Document document = new org.bson.Document("inner",
|
||||
new LinkedHashMap<>(new org.bson.Document("value", "FOO!")));
|
||||
|
||||
Outer outer = converter.read(Outer.class, document);
|
||||
assertThat(outer.inner).isNotNull();
|
||||
@@ -2520,6 +2522,88 @@ class MappingMongoConverterUnitTests {
|
||||
assertThat(target.typeImplementingMap).isEqualTo(new TypeImplementingMap("one", 2));
|
||||
}
|
||||
|
||||
@Test // GH-3686
|
||||
void readsCollectionContainingNullValue() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("items", Arrays.asList(new org.bson.Document("itemKey", "i1"), null, new org.bson.Document("itemKey", "i3")));
|
||||
|
||||
Order target = converter.read(Order.class, source);
|
||||
|
||||
assertThat(target.items)
|
||||
.map(it -> it != null ? it.itemKey : null)
|
||||
.containsExactly("i1", null, "i3");
|
||||
}
|
||||
|
||||
@Test // GH-3686
|
||||
void readsArrayContainingNullValue() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("arrayOfStrings", Arrays.asList("i1", null, "i3"));
|
||||
|
||||
WithArrays target = converter.read(WithArrays.class, source);
|
||||
|
||||
assertThat(target.arrayOfStrings).containsExactly("i1", null, "i3");
|
||||
}
|
||||
|
||||
@Test // GH-3686
|
||||
void readsMapContainingNullValue() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("mapOfObjects", new org.bson.Document("item1", "i1").append("item2", null).append("item3", "i3"));
|
||||
|
||||
ClassWithMapProperty target = converter.read(ClassWithMapProperty.class, source);
|
||||
|
||||
assertThat(target.mapOfObjects)
|
||||
.containsEntry("item1", "i1")
|
||||
.containsEntry("item2", null)
|
||||
.containsEntry("item3", "i3");
|
||||
}
|
||||
|
||||
@Test // GH-3670
|
||||
void appliesCustomConverterEvenToSimpleTypes() {
|
||||
|
||||
converter = new MappingMongoConverter(resolver, mappingContext);
|
||||
converter.setCustomConversions(MongoCustomConversions.create(it -> {
|
||||
it.registerConverter(new MongoSimpleTypeConverter());
|
||||
}));
|
||||
converter.afterPropertiesSet();
|
||||
|
||||
org.bson.Document source = new org.bson.Document("content", new Binary(new byte[] {0x00, 0x42}));
|
||||
|
||||
GenericType<Object> target = converter.read(GenericType.class, source);
|
||||
assertThat(target.content).isInstanceOf(byte[].class);
|
||||
}
|
||||
|
||||
@Test // GH-3702
|
||||
void readsRawDocument() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("_id", "id-1").append("raw", new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1)));
|
||||
|
||||
WithRawDocumentProperties target = converter.read(WithRawDocumentProperties.class, source);
|
||||
|
||||
assertThat(target.raw).isInstanceOf(org.bson.Document.class).isEqualTo( new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1)));
|
||||
}
|
||||
|
||||
@Test // GH-3702
|
||||
void readsListOfRawDocument() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("_id", "id-1").append("listOfRaw", Arrays.asList(new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1))));
|
||||
|
||||
WithRawDocumentProperties target = converter.read(WithRawDocumentProperties.class, source);
|
||||
|
||||
assertThat(target.listOfRaw)
|
||||
.containsExactly(new org.bson.Document("simple", 1).append("document", new org.bson.Document("inner-doc", 1)));
|
||||
}
|
||||
|
||||
@Test // GH-3692
|
||||
void readsMapThatDoesNotComeAsDocument() {
|
||||
|
||||
org.bson.Document source = new org.bson.Document("_id", "id-1").append("mapOfObjects", Collections.singletonMap("simple", 1));
|
||||
|
||||
ClassWithMapProperty target = converter.read(ClassWithMapProperty.class, source);
|
||||
|
||||
assertThat(target.mapOfObjects).containsEntry("simple",1);
|
||||
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -2881,6 +2965,10 @@ class MappingMongoConverterUnitTests {
|
||||
|
||||
}
|
||||
|
||||
static class WithArrays {
|
||||
String[] arrayOfStrings;
|
||||
}
|
||||
|
||||
// DATAMONGO-1898
|
||||
|
||||
// DATACMNS-1278
|
||||
@@ -3084,6 +3172,15 @@ class MappingMongoConverterUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@ReadingConverter
|
||||
public static class MongoSimpleTypeConverter implements Converter<Binary, Object> {
|
||||
|
||||
@Override
|
||||
public byte[] convert(Binary source) {
|
||||
return source.getData();
|
||||
}
|
||||
}
|
||||
|
||||
static class TypeWrappingTypeImplementingMap {
|
||||
|
||||
String id;
|
||||
@@ -3165,4 +3262,11 @@ class MappingMongoConverterUnitTests {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class WithRawDocumentProperties {
|
||||
|
||||
String id;
|
||||
org.bson.Document raw;
|
||||
List<org.bson.Document> listOfRaw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ import com.mongodb.client.model.Filters;
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author David Julia
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
@@ -739,6 +740,28 @@ public class QueryMapperUnitTests {
|
||||
assertThat(document).containsKey("map.1.stringProperty");
|
||||
}
|
||||
|
||||
@Test // GH-3688
|
||||
void mappingShouldRetainNestedNumericMapKeys() {
|
||||
|
||||
Query query = query(where("outerMap.1.map.2.stringProperty").is("ba'alzamon"));
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(EntityWithIntKeyedMapOfMap.class));
|
||||
|
||||
assertThat(document).containsKey("outerMap.1.map.2.stringProperty");
|
||||
}
|
||||
|
||||
@Test // GH-3688
|
||||
void mappingShouldAllowSettingEntireNestedNumericKeyedMapValue() {
|
||||
|
||||
Query query = query(where("outerMap.1.map").is(null)); //newEntityWithComplexValueTypeMap()
|
||||
|
||||
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
|
||||
context.getPersistentEntity(EntityWithIntKeyedMapOfMap.class));
|
||||
|
||||
assertThat(document).containsKey("outerMap.1.map");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1269
|
||||
void mappingShouldRetainNumericPositionInList() {
|
||||
|
||||
@@ -1465,6 +1488,10 @@ public class QueryMapperUnitTests {
|
||||
Map<Integer, SimpleEntityWithoutId> map;
|
||||
}
|
||||
|
||||
static class EntityWithIntKeyedMapOfMap{
|
||||
Map<Integer, EntityWithComplexValueTypeMap> outerMap;
|
||||
}
|
||||
|
||||
static class EntityWithComplexValueTypeList {
|
||||
List<SimpleEntityWithoutId> list;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ import com.mongodb.DBRef;
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
* @author Pavel Vodrazka
|
||||
* @author David Julia
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class UpdateMapperUnitTests {
|
||||
@@ -1179,6 +1180,16 @@ class UpdateMapperUnitTests {
|
||||
assertThat(mappedUpdate).isEqualTo("{\"$set\": {\"map.601218778970110001827396.value\": \"testing\"}}");
|
||||
}
|
||||
|
||||
@Test // GH-3688
|
||||
void multipleNumericKeysInNestedPath() {
|
||||
|
||||
Update update = new Update().set("intKeyedMap.12345.map.0", "testing");
|
||||
Document mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(EntityWithIntKeyedMap.class));
|
||||
|
||||
assertThat(mappedUpdate).isEqualTo("{\"$set\": {\"intKeyedMap.12345.map.0\": \"testing\"}}");
|
||||
}
|
||||
|
||||
@Test // GH-3566
|
||||
void mapsObjectClassPropertyFieldInMapValueTypeAsKey() {
|
||||
|
||||
@@ -1425,6 +1436,10 @@ class UpdateMapperUnitTests {
|
||||
Map<Object, NestedDocument> concreteMap;
|
||||
}
|
||||
|
||||
static class EntityWithIntKeyedMap{
|
||||
Map<Integer, EntityWithObjectMap> intKeyedMap;
|
||||
}
|
||||
|
||||
static class ClassWithEnum {
|
||||
|
||||
Allocation allocation;
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.dao.PermissionDeniedDataAccessException;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.mongodb.MongoDatabaseFactory;
|
||||
@@ -122,6 +124,20 @@ public class QuerydslMongoPredicateExecutorIntegrationTests {
|
||||
.containsExactly(dave);
|
||||
}
|
||||
|
||||
@Test // GH-3751
|
||||
public void findPage() {
|
||||
|
||||
assertThat(repository
|
||||
.findAll(person.lastname.startsWith(oliver.getLastname()).and(person.firstname.startsWith(dave.getFirstname())),
|
||||
PageRequest.of(0, 10))
|
||||
.getContent()).containsExactly(dave);
|
||||
|
||||
assertThat(repository
|
||||
.findAll(person.lastname.startsWith(oliver.getLastname()).and(person.firstname.startsWith(dave.getFirstname())),
|
||||
Pageable.unpaged())
|
||||
.getContent()).containsExactly(dave);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-362, DATAMONGO-1848
|
||||
public void springDataMongodbQueryShouldAllowJoinOnDBref() {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.bson.BsonDouble;
|
||||
import org.bson.BsonInt32;
|
||||
@@ -29,10 +29,16 @@ import org.bson.BsonString;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.mongodb.util.BsonUtils;
|
||||
|
||||
import com.mongodb.BasicDBList;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link BsonUtils}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class BsonUtilsTest {
|
||||
|
||||
@@ -111,4 +117,13 @@ class BsonUtilsTest {
|
||||
|
||||
assertThat((Collection)BsonUtils.asCollection(source)).containsExactly(source);
|
||||
}
|
||||
|
||||
@Test // GH-3702
|
||||
void supportsBsonShouldReportIfConversionSupported() {
|
||||
|
||||
assertThat(BsonUtils.supportsBson("foo")).isFalse();
|
||||
assertThat(BsonUtils.supportsBson(new Document())).isTrue();
|
||||
assertThat(BsonUtils.supportsBson(new BasicDBList())).isTrue();
|
||||
assertThat(BsonUtils.supportsBson(Collections.emptyMap())).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
Spring Data MongoDB Changelog
|
||||
=============================
|
||||
|
||||
Changes in version 3.2.3 (2021-07-16)
|
||||
-------------------------------------
|
||||
* #3702 - `MappingMongoConverter` incorrectly processes an object property of type `org.bson.Document`.
|
||||
* #3689 - Fix Regression in generating queries with nested maps with numeric keys.
|
||||
* #3688 - Multiple maps with numeric keys in a single update produces the wrong query (Regression).
|
||||
* #3686 - reading a document with a list with a null element fails with Spring Data Mongo 3.2.2, works with 3.2.1.
|
||||
* #3684 - Add equals and hashcode to UnwrappedMongoPersistentProperty (fixes #3683).
|
||||
* #3683 - Memory Leak: instances of UnwrappedMongoPersistentProperty are accumulating in PreferredConstructor.isPropertyParameterCache.
|
||||
* #3670 - `Binary` not deserialized to `byte[]` for property of type `Object`.
|
||||
|
||||
|
||||
Changes in version 3.2.2 (2021-06-22)
|
||||
-------------------------------------
|
||||
* #3677 - Add missing double quote to GeoJson.java JSDoc header.
|
||||
@@ -3464,5 +3475,6 @@ Repository
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Spring Data MongoDB 3.2.2 (2021.0.2)
|
||||
Spring Data MongoDB 3.2.4 (2021.0.4)
|
||||
Copyright (c) [2010-2019] Pivotal Software, Inc.
|
||||
|
||||
This product is licensed to you under the Apache License, Version 2.0 (the "License").
|
||||
@@ -26,6 +26,8 @@ conditions of the subcomponent's license, as noted in the LICENSE file.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user