Compare commits
12 Commits
2.2.5.RELE
...
2.2.6.RELE
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74c08fa8aa | ||
|
|
628aad8f64 | ||
|
|
39c8672e6d | ||
|
|
620991ddee | ||
|
|
ba8f28f623 | ||
|
|
6389055d3a | ||
|
|
4465ed9819 | ||
|
|
8dc97e5d01 | ||
|
|
a037c50961 | ||
|
|
28d5f02e15 | ||
|
|
e65a353fc4 | ||
|
|
42400e7836 |
6
pom.xml
6
pom.xml
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user