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.
This commit is contained in:
@@ -376,8 +376,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)
|
* @see org.springframework.data.mongodb.core.MongoOperations#executeAsStream(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
|
||||||
*/
|
*/
|
||||||
@Override
|
@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));
|
return stream(query, entityType, getCollectionName(entityType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,11 +385,11 @@ 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)
|
* @see org.springframework.data.mongodb.core.MongoOperations#stream(org.springframework.data.mongodb.core.query.Query, java.lang.Class, java.lang.String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@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);
|
return doStream(query, entityType, collectionName, entityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
Class<T> returnType) {
|
||||||
|
|
||||||
Assert.notNull(query, "Query must not be null!");
|
Assert.notNull(query, "Query must not be null!");
|
||||||
@@ -404,7 +403,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
|||||||
public CloseableIterator<T> doInCollection(MongoCollection<Document> collection)
|
public CloseableIterator<T> doInCollection(MongoCollection<Document> collection)
|
||||||
throws MongoException, DataAccessException {
|
throws MongoException, DataAccessException {
|
||||||
|
|
||||||
MongoPersistentEntity<?> persistentEntity = mappingContext.getRequiredPersistentEntity(entityType);
|
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityType);
|
||||||
|
|
||||||
Document mappedFields = getMappedFieldsObject(query.getFieldsObject(), persistentEntity, returnType);
|
Document mappedFields = getMappedFieldsObject(query.getFieldsObject(), persistentEntity, returnType);
|
||||||
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity);
|
Document mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity);
|
||||||
@@ -2419,7 +2418,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
|||||||
<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
|
<S, T> List<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
|
||||||
Class<T> targetClass, CursorPreparer preparer) {
|
Class<T> targetClass, CursorPreparer preparer) {
|
||||||
|
|
||||||
MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(sourceClass);
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(sourceClass);
|
||||||
|
|
||||||
Document mappedFields = getMappedFieldsObject(fields, entity, targetClass);
|
Document mappedFields = getMappedFieldsObject(fields, entity, targetClass);
|
||||||
Document mappedQuery = queryMapper.getMappedObject(query, entity);
|
Document mappedQuery = queryMapper.getMappedObject(query, entity);
|
||||||
@@ -2754,7 +2753,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware,
|
|||||||
return queryMapper.getMappedSort(query.getSortObject(), mappingContext.getPersistentEntity(type));
|
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,
|
Document projectedFields = propertyOperations.computeFieldsForProjection(projectionFactory, fields,
|
||||||
entity.getType(), targetType);
|
entity.getType(), targetType);
|
||||||
|
|||||||
@@ -375,8 +375,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
|||||||
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.Class)
|
* @see org.springframework.data.mongodb.core.ReactiveMongoOperations#reactiveIndexOps(java.lang.Class)
|
||||||
*/
|
*/
|
||||||
public ReactiveIndexOperations indexOps(Class<?> entityClass) {
|
public ReactiveIndexOperations indexOps(Class<?> entityClass) {
|
||||||
return new DefaultReactiveIndexOperations(this, getCollectionName(entityClass), this.queryMapper,
|
return new DefaultReactiveIndexOperations(this, getCollectionName(entityClass), this.queryMapper, entityClass);
|
||||||
entityClass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCollectionName(Class<?> entityClass) {
|
public String getCollectionName(Class<?> entityClass) {
|
||||||
@@ -615,8 +614,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
|||||||
*/
|
*/
|
||||||
public <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass,
|
public <T> Mono<MongoCollection<Document>> createCollection(Class<T> entityClass,
|
||||||
@Nullable CollectionOptions collectionOptions) {
|
@Nullable CollectionOptions collectionOptions) {
|
||||||
return doCreateCollection(getCollectionName(entityClass),
|
return doCreateCollection(getCollectionName(entityClass), convertToCreateCollectionOptions(collectionOptions, entityClass));
|
||||||
convertToCreateCollectionOptions(collectionOptions, entityClass));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1965,8 +1963,8 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
|||||||
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, Class<T> resultType, String mapFunction,
|
public <T> Flux<T> mapReduce(Query filterQuery, Class<?> domainType, Class<T> resultType, String mapFunction,
|
||||||
String reduceFunction, MapReduceOptions options) {
|
String reduceFunction, MapReduceOptions options) {
|
||||||
|
|
||||||
return mapReduce(filterQuery, domainType, getCollectionName(domainType), resultType, mapFunction,
|
return mapReduce(filterQuery, domainType, getCollectionName(domainType), resultType, mapFunction, reduceFunction,
|
||||||
reduceFunction, options);
|
options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2255,7 +2253,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
|||||||
<S, T> Flux<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
|
<S, T> Flux<T> doFind(String collectionName, Document query, Document fields, Class<S> sourceClass,
|
||||||
Class<T> targetClass, FindPublisherPreparer preparer) {
|
Class<T> targetClass, FindPublisherPreparer preparer) {
|
||||||
|
|
||||||
MongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(sourceClass);
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(sourceClass);
|
||||||
|
|
||||||
Document mappedFields = getMappedFieldsObject(fields, entity, targetClass);
|
Document mappedFields = getMappedFieldsObject(fields, entity, targetClass);
|
||||||
Document mappedQuery = queryMapper.getMappedObject(query, entity);
|
Document mappedQuery = queryMapper.getMappedObject(query, entity);
|
||||||
@@ -2269,7 +2267,12 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
|||||||
new ProjectingReadCallback<>(mongoConverter, sourceClass, targetClass, collectionName), collectionName);
|
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,
|
Document projectedFields = propertyOperations.computeFieldsForProjection(projectionFactory, fields,
|
||||||
entity.getType(), targetType);
|
entity.getType(), targetType);
|
||||||
|
|||||||
@@ -147,6 +147,13 @@ public class ExecutableFindOperationSupportTests {
|
|||||||
.hasSize(1);
|
.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
|
@Test // DATAMONGO-1563
|
||||||
public void findAllByWithProjection() {
|
public void findAllByWithProjection() {
|
||||||
|
|
||||||
|
|||||||
@@ -3346,7 +3346,7 @@ public class MongoTemplateTests {
|
|||||||
assertThat(loaded.bigDeciamVal, equalTo(new BigDecimal("800")));
|
assertThat(loaded.bigDeciamVal, equalTo(new BigDecimal("800")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAMONGO-1431
|
@Test // DATAMONGO-1431, DATAMONGO-2323
|
||||||
public void streamExecutionUsesExplicitCollectionName() {
|
public void streamExecutionUsesExplicitCollectionName() {
|
||||||
|
|
||||||
template.remove(new Query(), "some_special_collection");
|
template.remove(new Query(), "some_special_collection");
|
||||||
@@ -3357,14 +3357,14 @@ public class MongoTemplateTests {
|
|||||||
template.insert(document, "some_special_collection");
|
template.insert(document, "some_special_collection");
|
||||||
|
|
||||||
CloseableIterator<Document> stream = template.stream(new Query(), Document.class);
|
CloseableIterator<Document> stream = template.stream(new Query(), Document.class);
|
||||||
|
|
||||||
assertThat(stream.hasNext(), is(false));
|
assertThat(stream.hasNext(), is(false));
|
||||||
|
|
||||||
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(), is(true));
|
assertThat(stream2.hasNext()).isTrue();
|
||||||
assertThat(stream.next().id, is(document.id));
|
assertThat(stream2.next().get("_id")).isEqualTo(new ObjectId(document.id));
|
||||||
assertThat(stream.hasNext(), is(false));
|
assertThat(stream2.hasNext()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // DATAMONGO-1194
|
@Test // DATAMONGO-1194
|
||||||
|
|||||||
@@ -134,6 +134,12 @@ public class ReactiveFindOperationSupportTests {
|
|||||||
StepVerifier.create(template.query(Human.class).inCollection(STAR_WARS).all()).expectNextCount(2).verifyComplete();
|
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
|
@Test // DATAMONGO-1719
|
||||||
public void findAllWithProjection() {
|
public void findAllWithProjection() {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user