Compare commits

...

26 Commits

Author SHA1 Message Date
Jens Schauder
6ce5a26dc6 Release version 3.1.12 (2020.0.12).
See #3734
2021-08-12 10:25:55 +02:00
Jens Schauder
2716d1d503 Prepare 3.1.12 (2020.0.12).
See #3734
2021-08-12 10:25:34 +02:00
Mark Paluch
32223fc00a 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:23:42 +02:00
Jens Schauder
1884b7a97a After release cleanups.
See #3681
2021-07-16 10:45:19 +02:00
Jens Schauder
1f670bb5ed Prepare next development iteration.
See #3681
2021-07-16 10:45:17 +02:00
Jens Schauder
3e97d47248 Release version 3.1.11 (2020.0.11).
See #3681
2021-07-16 10:19:52 +02:00
Jens Schauder
c02840ca30 Prepare 3.1.11 (2020.0.11).
See #3681
2021-07-16 10:18:57 +02:00
Jens Schauder
975768c0d6 Updated changelog.
See #3681
2021-07-16 10:18:49 +02:00
Christoph Strobl
323ec3f1d6 Polishing.
Simplify KeyMapper current property/index setup.

Original Pull Request: #3689
2021-07-06 12:32:08 +02:00
David Julia
e480ceb2b7 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:12:46 +02:00
Mark Paluch
9fedd8d8c3 Updated changelog.
See #3650
2021-06-22 16:07:27 +02:00
Mark Paluch
baddae25da After release cleanups.
See #3649
2021-06-22 15:28:51 +02:00
Mark Paluch
5064cf3e9a Prepare next development iteration.
See #3649
2021-06-22 15:28:47 +02:00
Mark Paluch
81271a4f2f Release version 3.1.10 (2020.0.10).
See #3649
2021-06-22 15:18:22 +02:00
Mark Paluch
c36f9988c7 Prepare 3.1.10 (2020.0.10).
See #3649
2021-06-22 15:17:54 +02:00
Mark Paluch
b49beb08b6 Updated changelog.
See #3649
2021-06-22 15:17:49 +02:00
Mark Paluch
18b0946879 Update reference docs to use correct MongoClient.
Closes #3666
2021-06-22 14:36:58 +02:00
larsw
cf3681f7c2 Add closing quote to GeoJson javadoc.
Closes #3677
2021-06-21 13:58:44 +02:00
Christoph Strobl
49ef3fbc74 Polishing.
Fix typo in class name and make sure MongoTestTemplate uses the configured simple types.

See: #3659
Original pull request: #3661.
2021-06-18 14:22:08 +02:00
Christoph Strobl
01141502a0 Fix query mapper path resolution for types considered simple ones.
spring-projects/spring-data-commons#2293 changed how PersistentProperty paths get resolved and considers potentially registered converters for those, which made the path resolution fail in during the query mapping process.
This commit makes sure to capture the according exception and continue with the given user input.

Fixes: #3659
Original pull request: #3661.
2021-06-18 14:14:45 +02:00
Christoph Strobl
5d8f3d5c8b Fix $or / $nor keyword mapping in query mapper.
This commit fixes an issue with the pattern used for detecting $or / $nor which also matched other keywords like $floor.

Closes: #3635
Original pull request: #3637.
2021-06-18 13:55:46 +02:00
Mark Paluch
5cf801ff8e Polishing.
Add nullability annotation. Return early on null value conversion.

See #3633
Original pull request: #3643.
2021-06-09 14:20:46 +02:00
Christoph Strobl
2f3fb4aea9 Fix NPE in QueryMapper when trying to apply target type on null value.
Closes #3633
Original pull request: #3643.
2021-06-09 14:20:45 +02:00
Mark Paluch
82e05e7e8e Updated changelog.
See #3629
2021-05-14 12:36:39 +02:00
Mark Paluch
5be2e3eea2 After release cleanups.
See #3628
2021-05-14 12:05:20 +02:00
Mark Paluch
54f55e04de Prepare next development iteration.
See #3628
2021-05-14 12:05:16 +02:00
17 changed files with 276 additions and 37 deletions

View File

@@ -5,7 +5,7 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>3.1.9</version>
<version>3.1.12</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.4.9</version>
<version>2.4.12</version>
</parent>
<modules>
@@ -26,7 +26,7 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>2.4.9</springdata.commons>
<springdata.commons>2.4.12</springdata.commons>
<mongo>4.1.2</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.1.9</version>
<version>3.1.12</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.1.9</version>
<version>3.1.12</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.1.9</version>
<version>3.1.12</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -19,11 +19,14 @@ import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Example;
@@ -63,9 +66,12 @@ import com.mongodb.DBRef;
* @author Thomas Darimont
* @author Christoph Strobl
* @author Mark Paluch
* @author David Julia
*/
public class QueryMapper {
protected static final Logger LOGGER = LoggerFactory.getLogger(QueryMapper.class);
private static final List<String> DEFAULT_ID_NAMES = Arrays.asList("id", "_id");
private static final Document META_TEXT_SCORE = new Document("$meta", "textScore");
static final ClassTypeInformation<?> NESTED_DOCUMENT = ClassTypeInformation.from(NestedDocument.class);
@@ -378,6 +384,10 @@ public class QueryMapper {
}
}
if (value == null) {
return null;
}
if (isNestedKeyword(value)) {
return getMappedKeyword(new Keyword((Bson) value), documentField.getPropertyEntity());
}
@@ -635,7 +645,7 @@ public class QueryMapper {
* @param candidate
* @return
*/
protected boolean isNestedKeyword(Object candidate) {
protected boolean isNestedKeyword(@Nullable Object candidate) {
if (!(candidate instanceof Document)) {
return false;
@@ -680,12 +690,13 @@ public class QueryMapper {
* converted one by one.
*
* @param documentField the field and its meta data
* @param value the actual value
* @param value the actual value. Can be {@literal null}.
* @return the potentially converted target value.
*/
private Object applyFieldTargetTypeHintToValue(Field documentField, Object value) {
@Nullable
private Object applyFieldTargetTypeHintToValue(Field documentField, @Nullable Object value) {
if (documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) {
if (value == null || documentField.getProperty() == null || !documentField.getProperty().hasExplicitWriteTarget()) {
return value;
}
@@ -716,7 +727,6 @@ public class QueryMapper {
*/
static class Keyword {
private static final String N_OR_PATTERN = "\\$.*or";
private static final Set<String> NON_DBREF_CONVERTING_KEYWORDS = new HashSet<>(
Arrays.asList("$", "$size", "$slice", "$gt", "$lt"));
@@ -747,7 +757,7 @@ public class QueryMapper {
}
public boolean isOrOrNor() {
return key.matches(N_OR_PATTERN);
return key.equalsIgnoreCase("$or") || key.equalsIgnoreCase("$nor");
}
/**
@@ -1095,29 +1105,47 @@ public class QueryMapper {
return null;
}
try {
PersistentPropertyPath<MongoPersistentProperty> propertyPath = tryToResolvePersistentPropertyPath(path);
PersistentPropertyPath<MongoPersistentProperty> propertyPath = mappingContext.getPersistentPropertyPath(path);
if (propertyPath == null) {
Iterator<MongoPersistentProperty> iterator = propertyPath.iterator();
boolean associationDetected = false;
if (QueryMapper.LOGGER.isInfoEnabled()) {
while (iterator.hasNext()) {
String types = StringUtils.collectionToDelimitedString(
path.stream().map(it -> it.getType().getSimpleName()).collect(Collectors.toList()), " -> ");
QueryMapper.LOGGER.info(
"Could not map '{}'. Maybe a fragment in '{}' is considered a simple type. Mapper continues with {}.",
path, types, pathExpression);
}
return null;
}
MongoPersistentProperty property = iterator.next();
Iterator<MongoPersistentProperty> iterator = propertyPath.iterator();
boolean associationDetected = false;
if (property.isAssociation()) {
associationDetected = true;
continue;
}
while (iterator.hasNext()) {
if (associationDetected && !property.isIdProperty()) {
throw new MappingException(String.format(INVALID_ASSOCIATION_REFERENCE, pathExpression));
}
MongoPersistentProperty property = iterator.next();
if (property.isAssociation()) {
associationDetected = true;
continue;
}
return propertyPath;
} catch (InvalidPersistentPropertyPath e) {
if (associationDetected && !property.isIdProperty()) {
throw new MappingException(String.format(INVALID_ASSOCIATION_REFERENCE, pathExpression));
}
}
return propertyPath;
}
@Nullable
private PersistentPropertyPath<MongoPersistentProperty> tryToResolvePersistentPropertyPath(PropertyPath path) {
try {
return mappingContext.getPersistentPropertyPath(path);
} catch (MappingException e) {
return null;
}
}
@@ -1246,12 +1274,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;
}
/**
@@ -1263,21 +1296,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();
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

@@ -16,7 +16,7 @@
package org.springframework.data.mongodb.core.geo;
/**
* Interface definition for structures defined in <a href="https://geojson.org/>GeoJSON</a> format.
* Interface definition for structures defined in <a href="https://geojson.org/">GeoJSON</a> format.
*
* @author Christoph Strobl
* @since 1.7

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

@@ -36,7 +36,12 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.geo.Point;
@@ -70,8 +75,10 @@ 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)
public class QueryMapperUnitTests {
private QueryMapper mapper;
@@ -731,6 +738,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() {
@@ -1082,6 +1111,47 @@ public class QueryMapperUnitTests {
.isEqualTo(new org.bson.Document("double_underscore.renamed", new org.bson.Document("$exists", true)));
}
@Test // GH-3633
void mapsNullValueForFieldWithCustomTargetType() {
Query query = query(where("stringAsOid").is(null));
org.bson.Document document = mapper.getMappedObject(query.getQueryObject(),
context.getPersistentEntity(NonIdFieldWithObjectIdTargetType.class));
assertThat(document).isEqualTo(new org.bson.Document("stringAsOid", null));
}
@Test // GH-3635
void $floorKeywordDoesNotMatch$or$norPattern() {
Query query = new BasicQuery(" { $expr: { $gt: [ \"$spent\" , { $floor : \"$budget\" } ] } }");
assertThatNoException()
.isThrownBy(() -> mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(Foo.class)));
}
@Test // GH-3659
void allowsUsingFieldPathsForPropertiesHavingCustomConversionRegistered() {
Query query = query(where("address.street").is("1007 Mountain Drive"));
MongoCustomConversions mongoCustomConversions = new MongoCustomConversions(
Collections.singletonList(new MyAddressToDocumentConverter()));
this.context = new MongoMappingContext();
this.context.setSimpleTypeHolder(mongoCustomConversions.getSimpleTypeHolder());
this.context.afterPropertiesSet();
this.converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context);
this.converter.setCustomConversions(mongoCustomConversions);
this.converter.afterPropertiesSet();
this.mapper = new QueryMapper(converter);
assertThat(mapper.getMappedSort(query.getQueryObject(), context.getPersistentEntity(Customer.class)))
.isEqualTo(new org.bson.Document("address.street", "1007 Mountain Drive"));
}
class WithDeepArrayNesting {
List<WithNestedArray> level0;
@@ -1221,18 +1291,22 @@ public class QueryMapperUnitTests {
@Field("geoJsonPointWithNameViaFieldAnnotation") GeoJsonPoint namedGeoJsonPoint;
}
static class SimpeEntityWithoutId {
static class SimpleEntityWithoutId {
String stringProperty;
Integer integerProperty;
}
static class EntityWithComplexValueTypeMap {
Map<Integer, SimpeEntityWithoutId> map;
Map<Integer, SimpleEntityWithoutId> map;
}
static class EntityWithIntKeyedMapOfMap{
Map<Integer, EntityWithComplexValueTypeMap> outerMap;
}
static class EntityWithComplexValueTypeList {
List<SimpeEntityWithoutId> list;
List<SimpleEntityWithoutId> list;
}
static class WithExplicitTargetTypes {
@@ -1278,4 +1352,27 @@ public class QueryMapperUnitTests {
@Field("renamed") String renamed_fieldname_with_underscores;
}
@Document
static class Customer {
@Id private ObjectId id;
private String name;
private MyAddress address;
}
static class MyAddress {
private String street;
}
@WritingConverter
public static class MyAddressToDocumentConverter implements Converter<MyAddress, org.bson.Document> {
@Override
public org.bson.Document convert(MyAddress address) {
org.bson.Document doc = new org.bson.Document();
doc.put("street", address.street);
return doc;
}
}
}

View File

@@ -65,6 +65,7 @@ import com.mongodb.DBRef;
* @author Thomas Darimont
* @author Mark Paluch
* @author Pavel Vodrazka
* @author David Julia
*/
@ExtendWith(MockitoExtension.class)
class UpdateMapperUnitTests {
@@ -1110,6 +1111,16 @@ class UpdateMapperUnitTests {
.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() {
@@ -1357,6 +1368,10 @@ class UpdateMapperUnitTests {
Map<Object, NestedDocument> concreteMap;
}
static class EntityWithIntKeyedMap{
Map<Integer, EntityWithObjectMap> intKeyedMap;
}
static class ClassWithEnum {
Allocation allocation;

View File

@@ -60,7 +60,9 @@ import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.repository.Person.Sex;
import org.springframework.data.mongodb.repository.SampleEvaluationContextExtension.SampleSecurityContextHolder;
import org.springframework.data.querydsl.QSort;
@@ -1378,4 +1380,14 @@ public abstract class AbstractPersonRepositoryIntegrationTests {
void caseSensitiveInClauseIgnoresExpressions() {
assertThat(repository.findByFirstnameIn(".*")).isEmpty();
}
@Test // GH-3633
void annotatedQueryWithNullEqualityCheckShouldWork() {
operations.updateFirst(Query.query(Criteria.where("id").is(dave.getId())), Update.update("age", null), Person.class);
Person byQueryWithNullEqualityCheck = repository.findByQueryWithNullEqualityCheck();
assertThat(byQueryWithNullEqualityCheck.getId()).isEqualTo(dave.getId());
}
}

View File

@@ -403,4 +403,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
Person findPersonByManyArguments(String firstname, String lastname, String email, Integer age, Sex sex,
Date createdAt, List<String> skills, String street, String zipCode, //
String city, UUID uniqueId, String username, String password);
@Query("{ 'age' : null }")
Person findByQueryWithNullEqualityCheck();
}

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

@@ -119,6 +119,9 @@ public class MongoTestTemplateConfiguration {
mappingContext = new MongoMappingContext();
mappingContext.setInitialEntitySet(mappingContextConfigurer.initialEntitySet());
mappingContext.setAutoIndexCreation(mappingContextConfigurer.autocreateIndex);
if(mongoConverterConfigurer.customConversions != null) {
mappingContext.setSimpleTypeHolder(mongoConverterConfigurer.customConversions.getSimpleTypeHolder());
}
mappingContext.afterPropertiesSet();
}

View File

@@ -383,6 +383,13 @@ class ParameterBindingJsonReaderUnitTests {
.parse("{ 'stores.location' : { $geoWithin: { $centerSphere: [ [ 1.948516, 48.799029 ] , 0.004 ] } } }"));
}
@Test // GH-3633
void parsesNullValue() {
Document target = parse("{ 'parent' : null }");
assertThat(target).isEqualTo(new Document("parent", null));
}
private static Document parse(String json, Object... args) {
ParameterBindingJsonReader reader = new ParameterBindingJsonReader(json, args);

View File

@@ -214,7 +214,7 @@ public class AppConfig {
----
====
To access the `com.mongodb.client.MongoClient` object created by the `MongoClientFactoryBean` in other `@Configuration` classes or your own classes, use a `private @Autowired Mongo mongo;` field.
To access the `com.mongodb.client.MongoClient` object created by the `MongoClientFactoryBean` in other `@Configuration` classes or your own classes, use a `private @Autowired MongoClient mongoClient;` field.
[[mongo.mongo-xml-config]]
=== Registering a Mongo Instance by Using XML-based Metadata

View File

@@ -1,6 +1,38 @@
Spring Data MongoDB Changelog
=============================
Changes in version 3.1.11 (2021-07-16)
--------------------------------------
* #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).
Changes in version 3.2.2 (2021-06-22)
-------------------------------------
* #3677 - Add missing double quote to GeoJson.java JSDoc header.
* #3668 - Projection on the _id field returns wrong result when using `@MongoId` (MongoDB 4.4).
* #3666 - Documentation references outdated `Mongo` client.
* #3660 - MappingMongoConverter problem: ConversionContext#convert does not try to use custom converters first.
* #3659 - [3.2.1] Indexing Class with Custom Converter -> Couldn't find PersistentEntity for property private [...].
* #3635 - $floor isOrOrNor() return true.
* #3633 - NPE in QueryMapper when use Query with `null` as value.
Changes in version 3.1.10 (2021-06-22)
--------------------------------------
* #3677 - Add missing double quote to GeoJson.java JSDoc header.
* #3666 - Documentation references outdated `Mongo` client.
* #3659 - [3.2.1] Indexing Class with Custom Converter -> Couldn't find PersistentEntity for property private [...].
* #3635 - $floor isOrOrNor() return true.
* #3633 - NPE in QueryMapper when use Query with `null` as value.
Changes in version 3.2.1 (2021-05-14)
-------------------------------------
* #3638 - Introduce template method for easier customization of fragments.
* #3632 - Fix bullet points in aggregations framework asciidoc.
Changes in version 3.1.9 (2021-05-14)
-------------------------------------
@@ -3432,6 +3464,10 @@ Repository

View File

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