Compare commits

..

16 Commits

Author SHA1 Message Date
Mark Paluch
2b47f44531 DATAMONGO-2109 - Release version 2.0.12 (Kay SR12). 2018-11-27 11:45:49 +01:00
Mark Paluch
79534fa426 DATAMONGO-2109 - Prepare 2.0.12 (Kay SR12). 2018-11-27 11:44:58 +01:00
Mark Paluch
b8e76ecae4 DATAMONGO-2109 - Updated changelog. 2018-11-27 11:44:52 +01:00
Mark Paluch
3e2b060611 DATAMONGO-2110 - Updated changelog. 2018-11-27 11:27:23 +01:00
Mark Paluch
4699219728 DATAMONGO-2119 - Polishing.
Convert anonymous JSON callback class into a private static one. Use an expressive Pattern constant.

Original pull request: #621.
2018-11-23 09:56:24 +01:00
Christoph Strobl
a483d95cde DATAMONGO-2119 - Allow SpEL usage for annotated $regex query.
Original pull request: #621.
2018-11-23 09:56:24 +01:00
Oliver Drotbohm
84f35f5655 DATAMONGO-2135 - Polishing. 2018-11-15 15:30:41 +01:00
Oliver Drotbohm
2ec0f93325 DATAMONGO-2135 - Default to intermediate List for properties typed to Collection.
We now defensively create a List rather than a LinkedHashSet (which Spring's CollectionFactory.createCollection(…) defaults to) to make sure we're not accidentally dropping values that are considered equal according to their Java class definition.
2018-11-15 15:30:30 +01:00
Mark Paluch
48f9422a66 DATAMONGO-2107 - Updated changelog. 2018-10-29 14:30:33 +01:00
Mark Paluch
a2349405af DATAMONGO-2118 - Polishing.
Fix typo in reactive repositories reference documentation.

Original pull request: #611.
2018-10-26 10:08:07 +02:00
Mona Mohamadinia
e12ab354f7 DATAMONGO-2118 - Fix typo in repositories reference documentation.
Original pull request: #611.
2018-10-26 10:08:07 +02:00
Mark Paluch
04b20fa9c0 DATAMONGO-2098 - Polishing.
Annotate methods and parameters with Nullable. Use diamond syntax where appropriate.

Original pull request: #612.
2018-10-25 15:35:31 +02:00
Zied Yaich
81c46f04d6 DATAMONGO-2098 - Fix typo in MappingMongoConverterParser method.
Original pull request: #612.
2018-10-25 15:35:31 +02:00
Mark Paluch
ce905c80fe DATAMONGO-2083 - Updated changelog. 2018-10-15 14:19:05 +02:00
Mark Paluch
831e4f9ef1 DATAMONGO-2084 - After release cleanups. 2018-10-15 12:28:13 +02:00
Mark Paluch
5ce293a871 DATAMONGO-2084 - Prepare next development iteration. 2018-10-15 12:28:12 +02:00
14 changed files with 154 additions and 45 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.0.11.RELEASE</version>
<version>2.0.12.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.0.11.RELEASE</version>
<version>2.0.12.RELEASE</version>
</parent>
<modules>
@@ -27,7 +27,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.0.11.RELEASE</springdata.commons>
<springdata.commons>2.0.12.RELEASE</springdata.commons>
<mongo>3.5.0</mongo>
<mongo.reactivestreams>1.6.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.0.11.RELEASE</version>
<version>2.0.12.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.0.11.RELEASE</version>
<version>2.0.12.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -50,7 +50,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>2.0.11.RELEASE</version>
<version>2.0.12.RELEASE</version>
</dependency>
<!-- reactive -->

View File

@@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>2.0.11.RELEASE</version>
<version>2.0.12.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.0.11.RELEASE</version>
<version>2.0.12.RELEASE</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -60,6 +60,7 @@ import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexCre
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -75,6 +76,7 @@ import org.w3c.dom.Element;
* @author Thomas Darimont
* @author Christoph Strobl
* @author Mark Paluch
* @author Zied Yaich
*/
public class MappingMongoConverterParser implements BeanDefinitionParser {
@@ -159,6 +161,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
return null;
}
@Nullable
private BeanDefinition potentiallyCreateValidatingMongoEventListener(Element element, ParserContext parserContext) {
String disableValidation = element.getAttribute("disable-validation");
@@ -180,6 +183,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
return null;
}
@Nullable
private RuntimeBeanReference getValidator(Object source, ParserContext parserContext) {
if (!JSR_303_PRESENT) {
@@ -197,7 +201,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
}
public static String potentiallyCreateMappingContext(Element element, ParserContext parserContext,
BeanDefinition conversionsDefinition, String converterId) {
@Nullable BeanDefinition conversionsDefinition, @Nullable String converterId) {
String ctxRef = element.getAttribute("mapping-context-ref");
@@ -211,7 +215,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
BeanDefinitionBuilder mappingContextBuilder = BeanDefinitionBuilder
.genericBeanDefinition(MongoMappingContext.class);
Set<String> classesToAdd = getInititalEntityClasses(element);
Set<String> classesToAdd = getInitialEntityClasses(element);
if (classesToAdd != null) {
mappingContextBuilder.addPropertyValue("initialEntitySet", classesToAdd);
@@ -262,6 +266,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
}
}
@Nullable
private BeanDefinition getCustomConversions(Element element, ParserContext parserContext) {
List<Element> customConvertersElements = DomUtils.getChildElementsByTagName(element, "custom-converters");
@@ -269,7 +274,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
if (customConvertersElements.size() == 1) {
Element customerConvertersElement = customConvertersElements.get(0);
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<BeanMetadataElement>();
ManagedList<BeanMetadataElement> converterBeans = new ManagedList<>();
List<Element> converterElements = DomUtils.getChildElementsByTagName(customerConvertersElement, "converter");
if (converterElements != null) {
@@ -285,9 +290,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
provider.addExcludeFilter(new NegatingFilter(new AssignableTypeFilter(Converter.class),
new AssignableTypeFilter(GenericConverter.class)));
for (BeanDefinition candidate : provider.findCandidateComponents(packageToScan)) {
converterBeans.add(candidate);
}
converterBeans.addAll(provider.findCandidateComponents(packageToScan));
}
BeanDefinitionBuilder conversionsBuilder = BeanDefinitionBuilder.rootBeanDefinition(MongoCustomConversions.class);
@@ -304,7 +307,8 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
return null;
}
private static Set<String> getInititalEntityClasses(Element element) {
@Nullable
private static Set<String> getInitialEntityClasses(Element element) {
String basePackage = element.getAttribute(BASE_PACKAGE);
@@ -317,7 +321,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class));
componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class));
Set<String> classes = new ManagedSet<String>();
Set<String> classes = new ManagedSet<>();
for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) {
classes.add(candidate.getBeanClassName());
}
@@ -325,6 +329,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
return classes;
}
@Nullable
public BeanMetadataElement parseConverter(Element element, ParserContext parserContext) {
String converterRef = element.getAttribute("ref");
@@ -375,7 +380,7 @@ public class MappingMongoConverterParser implements BeanDefinitionParser {
Assert.notNull(filters, "TypeFilters must not be null");
this.delegates = new HashSet<TypeFilter>(Arrays.asList(filters));
this.delegates = new HashSet<>(Arrays.asList(filters));
}
/*

View File

@@ -578,7 +578,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return;
}
MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass())
MongoPersistentEntity<?> entity = isSubTypeOf(obj.getClass(), prop.getType())
? mappingContext.getRequiredPersistentEntity(obj.getClass())
: mappingContext.getRequiredPersistentEntity(type);
@@ -590,10 +590,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
accessor.put(prop, document);
}
private boolean isSubtype(Class<?> left, Class<?> right) {
return left.isAssignableFrom(right) && !left.equals(right);
}
/**
* 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
@@ -970,7 +966,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Assert.notNull(path, "Object path must not be null!");
Class<?> collectionType = targetType.getType();
collectionType = Collection.class.isAssignableFrom(collectionType) //
collectionType = isSubTypeOf(collectionType, Collection.class) //
? collectionType //
: List.class;
@@ -1544,6 +1540,17 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return true;
}
/**
* Returns whether the given type is a sub type of the given reference, i.e. assignable but not the exact same type.
*
* @param type must not be {@literal null}.
* @param reference must not be {@literal null}.
* @return
*/
private static boolean isSubTypeOf(Class<?> type, Class<?> reference) {
return !type.equals(reference) && reference.isAssignableFrom(type);
}
/**
* Marker class used to indicate we have a non root document object here that might be used within an update - so we
* need to preserve type hints for potential nested elements but need to remove it on top level.

View File

@@ -20,7 +20,9 @@ import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.bson.BSON;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,6 +39,7 @@ import org.springframework.util.StringUtils;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import com.mongodb.util.JSON;
import com.mongodb.util.JSONCallback;
/**
* Query to use a plain JSON String to create the {@link Query} to actually execute.
@@ -224,7 +227,8 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
String transformedInput = transformQueryAndCollectExpressionParametersIntoBindings(input, bindings);
String parseableInput = makeParameterReferencesParseable(transformedInput);
collectParameterReferencesIntoBindings(bindings, JSON.parse(parseableInput));
collectParameterReferencesIntoBindings(bindings,
JSON.parse(parseableInput, new LenientPatternDecodingCallback()));
return transformedInput;
}
@@ -359,6 +363,43 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
}
}
/**
* {@link JSONCallback} with lenient handling for {@link PatternSyntaxException} falling back to a placeholder
* {@link Pattern} for intermediate query document rendering.
*/
private static class LenientPatternDecodingCallback extends JSONCallback {
private static final Pattern EMPTY_MARKER = Pattern.compile("__Spring_Data_MongoDB_Bind_Marker__");
/*
* (non-Javadoc)
* @see com.mongodb.util.JSONCallback#objectDone()
*/
@Override
public Object objectDone() {
return exceptionSwallowingStackReducingObjectDone();
}
private Object exceptionSwallowingStackReducingObjectDone/*CauseWeJustNeedTheStructureNotTheActualValue*/() {
Object value;
try {
return super.objectDone();
} catch (PatternSyntaxException e) {
value = EMPTY_MARKER;
}
if (!isStackEmpty()) {
_put(curName(), value);
} else {
value = !BSON.hasDecodeHooks() ? value : BSON.applyDecodingHooks(value);
setRoot(value);
}
return value;
}
}
/**
* A generic parameter binding with name or position information.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2017 the original author or authors.
* Copyright 2011-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,28 +26,14 @@ import static org.junit.Assert.fail;
import static org.mockito.Mockito.*;
import static org.springframework.data.mongodb.core.DocumentTestUtils.*;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.*;
import org.bson.types.ObjectId;
import org.hamcrest.Matcher;
@@ -1904,6 +1890,18 @@ public class MappingMongoConverterUnitTests {
assertThat(target).doesNotContainKeys("_class");
}
@Test // DATAMONGO-2135
public void addsEqualObjectsToCollection() {
org.bson.Document itemDocument = new org.bson.Document("itemKey", "123");
org.bson.Document orderDocument = new org.bson.Document("items",
Arrays.asList(itemDocument, itemDocument, itemDocument));
Order order = converter.read(Order.class, orderDocument);
assertThat(order.items).hasSize(3);
}
static class GenericType<T> {
T content;
}
@@ -2284,4 +2282,15 @@ public class MappingMongoConverterUnitTests {
static class WithNestedLists {
float[][][] nestedFloats;
}
// DATAMONGO-2135
@EqualsAndHashCode // equality check by fields
static class SomeItem {
String itemKey;
}
static class Order {
Collection<SomeItem> items = new ArrayList<>();
}
}

View File

@@ -590,6 +590,19 @@ public class StringBasedMongoQueryUnitTests {
assertThat(query.getQueryObject(), is(new Document("arg0", null)));
}
@Test // DATAMONGO-2119
public void spelShouldIgnoreJsonParseErrorsForRegex() {
StringBasedMongoQuery mongoQuery = createQueryForMethod("findByPersonLastnameRegex", Person.class);
ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter,
new Person("Molly", "Chandler"));
org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor);
assertThat(query.getQueryObject().toJson(),
is(new BasicQuery("{lastname: {$regex: 'Chandler'}}").getQueryObject().toJson()));
}
private StringBasedMongoQuery createQueryForMethod(String name, Class<?>... parameters) {
try {
@@ -697,10 +710,14 @@ public class StringBasedMongoQueryUnitTests {
@Query("{ 'arg0' : '?0', 'arg1' : '?1s' }")
List<Person> findByWhenQuotedAndSomeStuffAppended(String arg0, String arg1);
@Query("{ 'lastname' : { '$regex' : '^(?0|John ?1|?1)'} }") // use spel or some regex string this is fucking bad
@Query("{ 'lastname' : { '$regex' : '^(?0|John ?1|?1)'} }") // use spel or some regex string this is bad
Person findByLastnameRegex(String lastname, String alternative);
@Query("{ arg0 : ?#{[0]} }")
List<Person> findByUsingSpel(Object arg0);
@Query("{ 'lastname' : { '$regex' : ?#{[0].lastname} } }")
Person findByPersonLastnameRegex(Person key);
}
}

View File

@@ -34,7 +34,7 @@ Note that the domain type shown in the preceding example has a property named `i
====
[source]
----
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {
// additional custom query methods go here
}

View File

@@ -47,7 +47,7 @@ Note that the entity defined in the preceding example has a property named `id`
====
[source]
----
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, Long> {
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
Flux<Person> findByFirstname(String firstname); <1>

View File

@@ -1,6 +1,36 @@
Spring Data MongoDB Changelog
=============================
Changes in version 2.0.12.RELEASE (2018-11-27)
----------------------------------------------
* DATAMONGO-2135 - Use List instead of Collection when reading data with MappingMongoConverter.
* DATAMONGO-2119 - Combining a SpEL expression and a $regex filter triggers a PatternSyntaxException.
* DATAMONGO-2118 - Fix typo in repositories reference documentation.
* DATAMONGO-2109 - Release 2.0.12 (Kay SR12).
* DATAMONGO-2098 - Typo in MappingMongoConverterParser.
Changes in version 1.10.17.RELEASE (2018-11-27)
-----------------------------------------------
* DATAMONGO-2135 - Use List instead of Collection when reading data with MappingMongoConverter.
* DATAMONGO-2118 - Fix typo in repositories reference documentation.
* DATAMONGO-2110 - Release 1.10.17 (Ingalls SR17).
Changes in version 2.1.2.RELEASE (2018-10-29)
---------------------------------------------
* DATAMONGO-2118 - Fix typo in repositories reference documentation.
* DATAMONGO-2113 - ChangeStreamTasks incorrectly converts resumeAt Instants into BsonTimestamp.
* DATAMONGO-2107 - Release 2.1.2 (Lovelace SR2).
* DATAMONGO-2098 - Typo in MappingMongoConverterParser.
Changes in version 1.10.16.RELEASE (2018-10-15)
-----------------------------------------------
* DATAMONGO-2096 - Aggregation.graphLookup.**.connectFrom(String) does not handle nested field.
* DATAMONGO-2083 - Release 1.10.16 (Ingalls SR16).
Changes in version 2.0.11.RELEASE (2018-10-15)
----------------------------------------------
* DATAMONGO-2101 - NoSuchMethodException: org.springframework.data.mongodb.core.geo.GeoJsonPoint.<init>().

View File

@@ -1,4 +1,4 @@
Spring Data MongoDB 2.0.11
Spring Data MongoDB 2.0.12
Copyright (c) [2010-2015] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").