From 1f146c3b5ca99de7874871dc2bb3f43bae65eedd Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 17 Jul 2019 14:28:11 +0200 Subject: [PATCH] =?UTF-8?q?DATAMONGO-2323=20-=20Fix=20query(=E2=80=A6)=20a?= =?UTF-8?q?nd=20stream(=E2=80=A6)=20to=20be=20used=20with=20BSON=20Documen?= =?UTF-8?q?t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MongoTemplate.stream(…), MongoTemplate.query(…) and ReactiveMongoTemplate.query(…) now no longer fail when used with BSON Document.class. Previously, field mapping failed because it required an entity type. Now we gracefully back off when find methods are used with a simple Document entity type. --- .../data/mongodb/core/MongoTemplate.java | 18 +++++++++++------- .../mongodb/core/ReactiveMongoTemplate.java | 19 +++++++++++-------- .../ExecutableFindOperationSupportTests.java | 7 +++++++ .../data/mongodb/core/MongoTemplateTests.java | 12 ++++++------ .../ReactiveFindOperationSupportTests.java | 6 ++++++ 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java index fb6e2e4e7..d97004f42 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java @@ -418,8 +418,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @see org.springframework.data.mongodb.core.MongoOperations#executeAsStream(org.springframework.data.mongodb.core.query.Query, java.lang.Class) */ @Override - public CloseableIterator stream(final Query query, final Class entityType) { - + public CloseableIterator stream(Query query, Class entityType) { return stream(query, entityType, getCollectionName(entityType)); } @@ -428,12 +427,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, * @see org.springframework.data.mongodb.core.MongoOperations#stream(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String) */ @Override - public CloseableIterator stream(final Query query, final Class entityType, final String collectionName) { + public CloseableIterator stream(Query query, Class entityType, String collectionName) { return doStream(query, entityType, collectionName, entityType); } @SuppressWarnings("ConstantConditions") - protected CloseableIterator doStream(final Query query, final Class entityType, final String collectionName, + protected CloseableIterator doStream(Query query, final Class entityType, String collectionName, Class returnType) { Assert.notNull(query, "Query must not be null!"); @@ -443,7 +442,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return execute(collectionName, (CollectionCallback>) collection -> { - MongoPersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(entityType); + MongoPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityType); Document mappedFields = getMappedFieldsObject(query.getFieldsObject(), persistentEntity, returnType); Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity); @@ -2523,7 +2522,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, List doFind(String collectionName, Document query, Document fields, Class sourceClass, Class targetClass, CursorPreparer preparer) { - MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(sourceClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(sourceClass); Document mappedFields = getMappedFieldsObject(fields, entity, targetClass); Document mappedQuery = queryMapper.getMappedObject(query, entity); @@ -2860,7 +2859,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, return queryMapper.getMappedSort(query.getSortObject(), mappingContext.getPersistentEntity(type)); } - private Document getMappedFieldsObject(Document fields, MongoPersistentEntity entity, Class targetType) { + private Document getMappedFieldsObject(Document fields, @Nullable MongoPersistentEntity entity, + Class targetType) { + + if (entity == null) { + return fields; + } Document projectedFields = propertyOperations.computeFieldsForProjection(projectionFactory, fields, entity.getType(), targetType); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java index 582da590f..411107e3e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java @@ -436,8 +436,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati * @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.Class) */ public ReactiveIndexOperations indexOps(Class entityClass) { - return new DefaultReactiveIndexOperations(this, getCollectionName(entityClass), this.queryMapper, - entityClass); + return new DefaultReactiveIndexOperations(this, getCollectionName(entityClass), this.queryMapper, entityClass); } public String getCollectionName(Class entityClass) { @@ -697,8 +696,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati () -> operations.forType(entityClass).getCollation()) // .map(options::collation).orElse(options); - return doCreateCollection(getCollectionName(entityClass), - convertToCreateCollectionOptions(options, entityClass)); + return doCreateCollection(getCollectionName(entityClass), convertToCreateCollectionOptions(options, entityClass)); } /* @@ -2103,8 +2101,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati public Flux mapReduce(Query filterQuery, Class domainType, Class resultType, String mapFunction, String reduceFunction, MapReduceOptions options) { - return mapReduce(filterQuery, domainType, getCollectionName(domainType), resultType, mapFunction, - reduceFunction, options); + return mapReduce(filterQuery, domainType, getCollectionName(domainType), resultType, mapFunction, reduceFunction, + options); } /* @@ -2402,7 +2400,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati Flux doFind(String collectionName, Document query, Document fields, Class sourceClass, Class targetClass, FindPublisherPreparer preparer) { - MongoPersistentEntity entity = mappingContext.getRequiredPersistentEntity(sourceClass); + MongoPersistentEntity entity = mappingContext.getPersistentEntity(sourceClass); Document mappedFields = getMappedFieldsObject(fields, entity, targetClass); Document mappedQuery = queryMapper.getMappedObject(query, entity); @@ -2416,7 +2414,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati new ProjectingReadCallback<>(mongoConverter, sourceClass, targetClass, collectionName), collectionName); } - private Document getMappedFieldsObject(Document fields, MongoPersistentEntity entity, Class targetType) { + private Document getMappedFieldsObject(Document fields, @Nullable MongoPersistentEntity entity, + Class targetType) { + + if (entity == null) { + return fields; + } Document projectedFields = propertyOperations.computeFieldsForProjection(projectionFactory, fields, entity.getType(), targetType); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java index b1377429a..9aff5442e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java @@ -147,6 +147,13 @@ public class ExecutableFindOperationSupportTests { .hasSize(1); } + @Test // DATAMONGO-2323 + public void findAllAsDocument() { + assertThat( + template.query(Document.class).inCollection(STAR_WARS).matching(query(where("firstname").is("luke"))).all()) + .hasSize(1); + } + @Test // DATAMONGO-1563 public void findAllByWithProjection() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index 53afe34e1..ea74dabf2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -3355,7 +3355,7 @@ public class MongoTemplateTests { assertThat(loaded.bigDeciamVal).isEqualTo(new BigDecimal("800")); } - @Test // DATAMONGO-1431 + @Test // DATAMONGO-1431, DATAMONGO-2323 public void streamExecutionUsesExplicitCollectionName() { template.remove(new Query(), "some_special_collection"); @@ -3366,14 +3366,14 @@ public class MongoTemplateTests { template.insert(document, "some_special_collection"); CloseableIterator stream = template.stream(new Query(), Document.class); - assertThat(stream.hasNext()).isFalse(); - stream = template.stream(new Query(), Document.class, "some_special_collection"); + CloseableIterator stream2 = template.stream(new Query(where("_id").is(document.id)), + org.bson.Document.class, "some_special_collection"); - assertThat(stream.hasNext()).isTrue(); - assertThat(stream.next().id).isEqualTo(document.id); - assertThat(stream.hasNext()).isFalse(); + assertThat(stream2.hasNext()).isTrue(); + assertThat(stream2.next().get("_id")).isEqualTo(new ObjectId(document.id)); + assertThat(stream2.hasNext()).isFalse(); } @Test // DATAMONGO-1194 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java index c94425f45..ee59f67e5 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java @@ -134,6 +134,12 @@ public class ReactiveFindOperationSupportTests { StepVerifier.create(template.query(Human.class).inCollection(STAR_WARS).all()).expectNextCount(2).verifyComplete(); } + @Test // DATAMONGO-2323 + public void findAllAsDocumentDocument() { + StepVerifier.create(template.query(Document.class).inCollection(STAR_WARS).all()).expectNextCount(2) + .verifyComplete(); + } + @Test // DATAMONGO-1719 public void findAllWithProjection() {