Browse Source

DATAMONGO-2323 - Fix query(…) and stream(…) to be used with BSON Document.

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.
pull/773/head
Mark Paluch 7 years ago
parent
commit
1f146c3b5c
  1. 18
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  2. 19
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java
  3. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java
  4. 12
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  5. 6
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java

18
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java

@ -418,8 +418,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -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 <T> CloseableIterator<T> stream(final Query query, final Class<T> entityType) {
public <T> CloseableIterator<T> stream(Query query, Class<T> entityType) {
return stream(query, entityType, getCollectionName(entityType));
}
@ -428,12 +427,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -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 <T> CloseableIterator<T> stream(final Query query, final Class<T> entityType, final String collectionName) {
public <T> CloseableIterator<T> stream(Query query, Class<T> entityType, String collectionName) {
return doStream(query, entityType, collectionName, entityType);
}
@SuppressWarnings("ConstantConditions")
protected <T> CloseableIterator<T> doStream(final Query query, final Class<?> entityType, final String collectionName,
protected <T> CloseableIterator<T> doStream(Query query, final Class<?> entityType, String collectionName,
Class<T> returnType) {
Assert.notNull(query, "Query must not be null!");
@ -443,7 +442,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, @@ -443,7 +442,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
return execute(collectionName, (CollectionCallback<CloseableIterator<T>>) 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, @@ -2523,7 +2522,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
Class<T> 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, @@ -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);

19
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ReactiveMongoTemplate.java

@ -436,8 +436,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati @@ -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 @@ -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 @@ -2103,8 +2101,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, Class<T> 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 @@ -2402,7 +2400,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
<S, T> Flux<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
Class<T> 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 @@ -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);

7
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java

@ -147,6 +147,13 @@ public class ExecutableFindOperationSupportTests { @@ -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() {

12
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -3355,7 +3355,7 @@ public class MongoTemplateTests { @@ -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 { @@ -3366,14 +3366,14 @@ public class MongoTemplateTests {
template.insert(document, "some_special_collection");
CloseableIterator<Document> stream = template.stream(new Query(), Document.class);
assertThat(stream.hasNext()).isFalse();
stream = template.stream(new Query(), Document.class, "some_special_collection");
CloseableIterator<org.bson.Document> 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

6
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ReactiveFindOperationSupportTests.java

@ -134,6 +134,12 @@ public class ReactiveFindOperationSupportTests { @@ -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() {

Loading…
Cancel
Save