Compare commits

..

18 Commits
3.2.2 ... 3.2.4

Author SHA1 Message Date
Jens Schauder
7385262c47 Release version 3.2.4 (2021.0.4).
See #3735
2021-08-12 11:22:50 +02:00
Jens Schauder
259938588a Prepare 3.2.4 (2021.0.4).
See #3735
2021-08-12 11:22:26 +02:00
Mark Paluch
a1b4e3fc55 Run unpaged query using Pageable.unpaged() through QuerydslMongoPredicateExecutor.findAll(…).
We now correctly consider unpaged queries if the Pageable is unpaged.

Closes: #3751
Original Pull Request: #3754
2021-07-26 15:16:30 +02:00
Jens Schauder
76479820bc After release cleanups.
See #3682
2021-07-16 11:51:05 +02:00
Jens Schauder
c47bbc4a20 Prepare next development iteration.
See #3682
2021-07-16 11:51:02 +02:00
Jens Schauder
74791d0bca Release version 3.2.3 (2021.0.3).
See #3682
2021-07-16 11:35:22 +02:00
Jens Schauder
f4d2287011 Prepare 3.2.3 (2021.0.3).
See #3682
2021-07-16 11:34:27 +02:00
Jens Schauder
ab6ba194c1 Updated changelog.
See #3682
2021-07-16 11:34:20 +02:00
Mark Paluch
595a346705 Polishing.
Support DBObject and Map that as source for entity materialization and map conversion.

See #3702
Original pull request: #3704.
2021-07-15 10:00:00 +02:00
Christoph Strobl
08c5e5a810 Fix raw document conversion in Collection like properties.
Along the lines make sure to convert map like structures correctly if they do not come as a Document, eg. cause they got converted to a plain Map in a post load, pre convert event.

Closes #3702
Original pull request: #3704.
2021-07-15 09:59:50 +02:00
Christoph Strobl
f987217c3c Custom Converter should also be applicable for simple types.
This commit fixes a regression that prevented custom converters from being applied to types considered store native ones.

Original pull request: #3703.
Fixes #3670
2021-07-15 09:00:35 +02:00
Christoph Strobl
92a22978c2 Polishing.
Simplify KeyMapper current property/index setup.

Original Pull Request: #3689
2021-07-06 12:56:10 +02:00
David Julia
2e2e076b5b Fix Regression in generating queries with nested maps with numeric keys.
While maps that have numeric keys work if there is only one map with an integer key, when there are multiple maps with numeric keys in a given query, it fails.

Take the following example for a map called outer with numeric keys holding reference to another object with a map called inner with numeric keys: Updates that are meant to generate {"$set": {"outerMap.1234.inner.5678": "hello"}} are instead generating {"$set": {"outerMap.1234.inner.inner": "hello"}}, repeating the later map property name instead of using the integer key value.

This commit adds unit tests both for the UpdateMapper and QueryMapper, which check multiple consecutive maps with numeric keys, and adds a fix in the KeyMapper. Because we cannot easily change the path parsing to somehow parse path parts corresponding to map keys differently, we address the issue in the KeyMapper. We keep track of the partial path corresponding to the current property and use it to skip adding the duplicated property name for the map to the query, and instead add the key.

This is a bit redundant in that we now have both an iterator and an index-based way of accessing the path parts, but it gets the tests passing and fixes the issue without making a large change to the current approach.

Fixes: #3688
Original Pull Request: #3689
2021-07-06 12:05:58 +02:00
Christoph Strobl
0c50d97887 Fix NPE when reading/mapping null value inside collection.
Closes: #3686
2021-07-01 11:16:13 +02:00
Christoph Strobl
c10d4b6af0 Favor ObjectUtils over Objects for equals/hashCode.
Original Pull Request: #3684
2021-06-24 13:43:55 +02:00
Gatto
6644ac6875 Add equals and hashCode to UnwrappedMongoPersistentProperty.
Fixes #3683
Original Pull Request: #3684
2021-06-24 13:42:12 +02:00
Mark Paluch
708def0df1 After release cleanups.
See #3650
2021-06-22 16:05:22 +02:00
Mark Paluch
889e5d52bb Prepare next development iteration.
See #3650
2021-06-22 16:05:19 +02:00
17 changed files with 354 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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