Compare commits

...

12 Commits

Author SHA1 Message Date
Mark Paluch
74c08fa8aa DATAMONGO-2485 - Release version 2.2.6 (Moore SR6). 2020-03-25 10:46:02 +01:00
Mark Paluch
628aad8f64 DATAMONGO-2485 - Prepare 2.2.6 (Moore SR6). 2020-03-25 10:45:35 +01:00
Mark Paluch
39c8672e6d DATAMONGO-2485 - Updated changelog. 2020-03-25 10:45:28 +01:00
Christoph Strobl
620991ddee DATAMONGO-2300 - Polishing.
Move null check to event publishing logic.

Original Pull Request: #763
2020-03-23 10:11:41 +01:00
Heesu Jung
ba8f28f623 DATAMONGO-2300 - Add check rawType is null in readMap.
Original Pull Request: #763
2020-03-23 10:01:50 +01:00
Mark Paluch
6389055d3a DATAMONGO-2497 - Update documentation regarding @Transient properties usage in the persistence constructor. 2020-03-19 15:37:37 +01:00
Christoph Strobl
4465ed9819 DATAMONGO-2445 - Deprecate ReactiveGridFsOperations using AsyncInputStream.
Methods using AsyncInputStream will be removed in 3.0. Please use the ones accepting a Publisher.

Original pull request: #843.
2020-03-19 09:42:49 +01:00
Mark Paluch
8dc97e5d01 DATAMONGO-2488 - Polishing.
Simplify conditional entity check.

Original pull request: #841.
2020-03-11 14:38:17 +01:00
Christoph Strobl
a037c50961 DATAMONGO-2488 - Fix nested array path field name mapping.
Original pull request: #841.
2020-03-11 14:38:16 +01:00
Jens Schauder
28d5f02e15 DATAMONGO-2473 - Updated changelog. 2020-03-11 09:59:36 +01:00
Mark Paluch
e65a353fc4 DATAMONGO-2453 - After release cleanups. 2020-02-26 11:54:09 +01:00
Mark Paluch
42400e7836 DATAMONGO-2453 - Prepare next development iteration. 2020-02-26 11:54:08 +01:00
13 changed files with 159 additions and 21 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
</parent>
<modules>
@@ -26,7 +26,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.2.5.RELEASE</springdata.commons>
<springdata.commons>2.2.6.RELEASE</springdata.commons>
<mongo>3.11.2</mongo>
<mongo.reactivestreams>1.12.0</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>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</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>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.2.5.RELEASE</version>
<version>2.2.6.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -90,6 +90,7 @@ import com.mongodb.DBRef;
* @author Christoph Strobl
* @author Jordi Llach
* @author Mark Paluch
* @author Heesu Jung
*/
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
@@ -1574,7 +1575,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@Nullable
private <T> T readAndConvertDBRef(@Nullable DBRef dbref, TypeInformation<?> type, ObjectPath path,
final Class<?> rawType) {
@Nullable Class<?> rawType) {
List<T> result = bulkReadAndConvertDBRefs(Collections.singletonList(dbref), type, path, rawType);
return CollectionUtils.isEmpty(result) ? null : result.iterator().next();
@@ -1597,7 +1598,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
@SuppressWarnings("unchecked")
private <T> List<T> bulkReadAndConvertDBRefs(List<DBRef> dbrefs, TypeInformation<?> type, ObjectPath path,
final Class<?> rawType) {
@Nullable Class<?> rawType) {
if (CollectionUtils.isEmpty(dbrefs)) {
return Collections.emptyList();
@@ -1613,7 +1614,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
for (Document document : referencedRawDocuments) {
if (document != null) {
maybeEmitEvent(new AfterLoadEvent<>(document, (Class<T>) rawType, collectionName));
maybeEmitEvent(
new AfterLoadEvent<>(document, (Class<T>) (rawType != null ? rawType : Object.class), collectionName));
}
final T target = (T) read(type, document, path);

View File

@@ -24,7 +24,6 @@ import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Example;
@@ -175,7 +174,7 @@ public class QueryMapper {
}
Document mappedSort = new Document();
for(Map.Entry<String,Object> entry : BsonUtils.asMap(sortObject).entrySet()) {
for (Map.Entry<String, Object> entry : BsonUtils.asMap(sortObject).entrySet()) {
Field field = createPropertyField(entity, entry.getKey(), mappingContext);
mappedSort.put(field.getMappedKey(), entry.getValue());
@@ -1158,7 +1157,7 @@ public class QueryMapper {
* @return
*/
protected Converter<MongoPersistentProperty, String> getPropertyConverter() {
return new PositionParameterRetainingPropertyKeyConverter(name);
return new PositionParameterRetainingPropertyKeyConverter(name, mappingContext);
}
/**
@@ -1172,6 +1171,10 @@ public class QueryMapper {
return new AssociationConverter(getAssociation());
}
protected MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> getMappingContext() {
return mappingContext;
}
/**
* @author Christoph Strobl
* @since 1.8
@@ -1180,8 +1183,9 @@ public class QueryMapper {
private final KeyMapper keyMapper;
public PositionParameterRetainingPropertyKeyConverter(String rawKey) {
this.keyMapper = new KeyMapper(rawKey);
public PositionParameterRetainingPropertyKeyConverter(String rawKey,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> ctx) {
this.keyMapper = new KeyMapper(rawKey, ctx);
}
/*
@@ -1222,11 +1226,14 @@ public class QueryMapper {
static class KeyMapper {
private final Iterator<String> iterator;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
public KeyMapper(String key) {
public KeyMapper(String key,
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext) {
this.iterator = Arrays.asList(key.split("\\.")).iterator();
this.iterator.next();
this.mappingContext = mappingContext;
}
/**
@@ -1240,9 +1247,21 @@ public class QueryMapper {
StringBuilder mappedName = new StringBuilder(PropertyToFieldNameConverter.INSTANCE.convert(property));
boolean inspect = iterator.hasNext();
int depth = 0;
while (inspect) {
String partial = iterator.next();
if (depth > 0 && property.isCollectionLike() && property.isEntity() && property.getComponentType() != null) {
MongoPersistentEntity<?> persistentEntity = mappingContext
.getRequiredPersistentEntity(property.getComponentType());
MongoPersistentProperty persistentProperty = persistentEntity.getPersistentProperty(partial);
if (persistentProperty != null) {
partial = mapPropertyName(persistentProperty);
}
}
boolean isPositional = (isPositionalParameter(partial) && (property.isMap() || property.isCollectionLike()));
if (isPositional) {
@@ -1250,6 +1269,7 @@ public class QueryMapper {
}
inspect = isPositional && iterator.hasNext();
depth++;
}
return mappedName.toString();

View File

@@ -308,7 +308,7 @@ public class UpdateMapper extends QueryMapper {
*/
@Override
protected Converter<MongoPersistentProperty, String> getPropertyConverter() {
return new PositionParameterRetainingPropertyKeyConverter(key);
return new PositionParameterRetainingPropertyKeyConverter(key, getMappingContext());
}
/*
@@ -317,7 +317,7 @@ public class UpdateMapper extends QueryMapper {
*/
@Override
protected Converter<MongoPersistentProperty, String> getAssociationConverter() {
return new UpdateAssociationConverter(getAssociation(), key);
return new UpdateAssociationConverter(getMappingContext(), getAssociation(), key);
}
/**
@@ -334,10 +334,12 @@ public class UpdateMapper extends QueryMapper {
*
* @param association must not be {@literal null}.
*/
public UpdateAssociationConverter(Association<MongoPersistentProperty> association, String key) {
public UpdateAssociationConverter(
MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext,
Association<MongoPersistentProperty> association, String key) {
super(association);
this.mapper = new KeyMapper(key);
this.mapper = new KeyMapper(key, mappingContext);
}
/*

View File

@@ -111,7 +111,10 @@ public interface ReactiveGridFsOperations {
* @param metadata can be {@literal null}
* @return a {@link Mono} emitting the {@link ObjectId} of the {@link com.mongodb.client.gridfs.model.GridFSFile} just
* created.
* @deprecated since 2.2.6. Will be removed in 3.0. Please use {@link #store(Publisher, String, String, Object)}
* instead.
*/
@Deprecated
Mono<ObjectId> store(AsyncInputStream content, @Nullable String filename, @Nullable String contentType,
@Nullable Object metadata);
@@ -151,7 +154,10 @@ public interface ReactiveGridFsOperations {
* @param metadata can be {@literal null}.
* @return a {@link Mono} emitting the {@link ObjectId} of the {@link com.mongodb.client.gridfs.model.GridFSFile} just
* created.
* @deprecated since 2.2.6. Will be removed in 3.0. Please use {@link #store(Publisher, String, String, Document)}
* instead.
*/
@Deprecated
Mono<ObjectId> store(AsyncInputStream content, @Nullable String filename, @Nullable String contentType,
@Nullable Document metadata);

View File

@@ -88,6 +88,7 @@ import com.mongodb.DBRef;
* @author Patrik Wasik
* @author Christoph Strobl
* @author Mark Paluch
* @author Heesu Jung
*/
@RunWith(MockitoJUnitRunner.class)
public class MappingMongoConverterUnitTests {
@@ -2078,6 +2079,23 @@ public class MappingMongoConverterUnitTests {
.isEqualTo(new BasicDBObject("property", "value"));
}
@Test // DATAMONGO-2300
public void readAndConvertDBRefNestedByMapCorrectly() {
org.bson.Document cluster = new org.bson.Document("_id", 100L);
DBRef dbRef = new DBRef("clusters", 100L);
org.bson.Document data = new org.bson.Document("_id", 3L);
data.append("cluster", dbRef);
MappingMongoConverter spyConverter = spy(converter);
Mockito.doReturn(cluster).when(spyConverter).readRef(dbRef);
Map<Object, Object> result = spyConverter.readMap(ClassTypeInformation.MAP, data, ObjectPath.ROOT);
assertThat(((LinkedHashMap) result.get("cluster")).get("_id")).isEqualTo(100L);
}
static class GenericType<T> {
T content;
}

View File

@@ -927,6 +927,70 @@ public class QueryMapperUnitTests {
assertThat(target).isEqualTo(org.bson.Document.parse("{\"_id\": {\"$in\": [{\"$oid\": \"" + id + "\"}]}}"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForNonMatchingPath() {
org.bson.Document target = mapper.getMappedObject(
query(where("array.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(Foo.class));
assertThat(target).isEqualTo(new org.bson.Document("array.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForObjectTargetArray() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayObj.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayObj.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsNestedArrayPathCorrectlyForStringTargetArray() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayString.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayString.$[some_item].nested.$[other_item]", "value"));
}
@Test // DATAMONGO-2488
public void mapsCustomFieldNamesForNestedArrayPathCorrectly() {
org.bson.Document target = mapper.getMappedObject(
query(where("arrayCustomName.$[some_item].nested.$[other_item]").is("value")).getQueryObject(),
context.getPersistentEntity(WithNestedArray.class));
assertThat(target).isEqualTo(new org.bson.Document("arrayCustomName.$[some_item].nes-ted.$[other_item]", "value"));
}
class WithNestedArray {
List<NestedArrayOfObj> arrayObj;
List<NestedArrayOfString> arrayString;
List<NestedArrayOfObjCustomFieldName> arrayCustomName;
}
class NestedArrayOfObj {
List<ArrayObj> nested;
}
class NestedArrayOfObjCustomFieldName {
@Field("nes-ted") List<ArrayObj> nested;
}
class NestedArrayOfString {
List<String> nested;
}
class ArrayObj {
String foo;
}
@Document
public class Foo {
@Id private ObjectId id;

View File

@@ -416,7 +416,7 @@ The MappingMongoConverter can use metadata to drive the mapping of objects to do
* `@TextIndexed`: Applied at the field level to mark the field to be included in the text index.
* `@HashIndexed`: Applied at the field level for usage within a hashed index to partition data across a sharded cluster.
* `@Language`: Applied at the field level to set the language override property for text index.
* `@Transient`: By default all private fields are mapped to the document, this annotation excludes the field where it is applied from being stored in the database
* `@Transient`: By default, all fields are mapped to the document. This annotation excludes the field where it is applied from being stored in the database. Transient properties cannot be used within a persistence constructor as the converter cannot materialize a value for the constructor argument.
* `@PersistenceConstructor`: Marks a given constructor - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved Document.
* `@Value`: This annotation is part of the Spring Framework . Within the mapping framework it can be applied to constructor arguments. This lets you use a Spring Expression Language statement to transform a key's value retrieved in the database before it is used to construct a domain object. In order to reference a property of a given document one has to use expressions like: `@Value("#root.myProperty")` where `root` refers to the root of the given document.
* `@Field`: Applied at the field level it allows to describe the name and type of the field as it will be represented in the MongoDB BSON document thus allowing the name and type to be different than the fieldname of the class as well as the property type.

View File

@@ -1,6 +1,29 @@
Spring Data MongoDB Changelog
=============================
Changes in version 2.2.6.RELEASE (2020-03-25)
---------------------------------------------
* DATAMONGO-2497 - Update documentation regarding @Transient properties usage in the persistence constructor.
* DATAMONGO-2488 - KeyMapper.mapPropertyName does not work for nested arrays.
* DATAMONGO-2485 - Release 2.2.6 (Moore SR6).
* DATAMONGO-2445 - Deprecate ReactiveGridFs methods using AsyncInputStream.
* DATAMONGO-2300 - Can't read and convert DBRef when the type is Map.
Changes in version 3.0.0.M4 (2020-03-11)
----------------------------------------
* DATAMONGO-2491 - Adapt to Mockito 3.3 changes.
* DATAMONGO-2489 - Upgrade to MongoDB Driver 4.0.
* DATAMONGO-2481 - Speed up build.
* DATAMONGO-2478 - NPE when using Query annotation and with sort and pageable.
* DATAMONGO-2476 - JsonParseException: JSON reader was expecting a value but found '}'.
* DATAMONGO-2474 - Upgrade to MongoDB Driver 4.0.0-rc0.
* DATAMONGO-2473 - Release 3.0 M4 (Neumann).
* DATAMONGO-2363 - Add support for $merge aggregation stage.
* DATAMONGO-2355 - Revise Abstract…MongoConfiguration to expose more bean detail and avoid proxying.
* DATAMONGO-2341 - Support shard key derivation.
Changes in version 2.2.5.RELEASE (2020-02-26)
---------------------------------------------
* DATAMONGO-2478 - NPE when using Query annotation and with sort and pageable.
@@ -2935,3 +2958,5 @@ Repository

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 2.2.5
Spring Data MongoDB 2.2.6
Copyright (c) [2010-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -11,3 +11,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file.