|
|
|
@ -111,11 +111,9 @@ import org.springframework.data.mongodb.core.query.UpdateDefinition.ArrayFilter; |
|
|
|
import org.springframework.data.mongodb.core.timeseries.Granularity; |
|
|
|
import org.springframework.data.mongodb.core.timeseries.Granularity; |
|
|
|
import org.springframework.data.mongodb.core.validation.Validator; |
|
|
|
import org.springframework.data.mongodb.core.validation.Validator; |
|
|
|
import org.springframework.data.projection.EntityProjection; |
|
|
|
import org.springframework.data.projection.EntityProjection; |
|
|
|
import org.springframework.data.projection.ProjectionFactory; |
|
|
|
|
|
|
|
import org.springframework.data.util.CloseableIterator; |
|
|
|
import org.springframework.data.util.CloseableIterator; |
|
|
|
import org.springframework.data.util.Lazy; |
|
|
|
import org.springframework.data.util.Lazy; |
|
|
|
import org.springframework.data.util.Optionals; |
|
|
|
import org.springframework.data.util.Optionals; |
|
|
|
import org.springframework.data.util.TypeInformation; |
|
|
|
|
|
|
|
import org.springframework.lang.Contract; |
|
|
|
import org.springframework.lang.Contract; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
@ -523,8 +521,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<R> resultReader = getResultReader(projection, collectionName, resultConverter); |
|
|
|
DocumentCallback<R> resultReader = getResultReader(projection, collectionName, resultConverter); |
|
|
|
|
|
|
|
|
|
|
|
return new CloseableIterableCursorAdapter<>(cursor, exceptionTranslator, |
|
|
|
return new CloseableIterableCursorAdapter<>(cursor, exceptionTranslator, resultReader).stream(); |
|
|
|
resultReader).stream(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -1183,11 +1180,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public <S, T> @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, |
|
|
|
public <S, T> @Nullable T findAndReplace(Query query, S replacement, FindAndReplaceOptions options, |
|
|
|
Class<S> entityType, String collectionName, Class<T> resultType) { |
|
|
|
Class<S> entityType, String collectionName, Class<T> resultType) { |
|
|
|
return findAndReplace(query, replacement, options, entityType, collectionName, resultType, QueryResultConverter.entity()); |
|
|
|
return findAndReplace(query, replacement, options, entityType, collectionName, resultType, |
|
|
|
|
|
|
|
QueryResultConverter.entity()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
<S, T, R> @Nullable R findAndReplace(Query query, S replacement, FindAndReplaceOptions options, |
|
|
|
<S, T, R> @Nullable R findAndReplace(Query query, S replacement, FindAndReplaceOptions options, Class<S> entityType, |
|
|
|
Class<S> entityType, String collectionName, Class<T> resultType, QueryResultConverter<? super T, ? extends R> resultConverter) { |
|
|
|
String collectionName, Class<T> resultType, QueryResultConverter<? super T, ? extends R> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(query, "Query must not be null"); |
|
|
|
Assert.notNull(replacement, "Replacement must not be null"); |
|
|
|
Assert.notNull(replacement, "Replacement must not be null"); |
|
|
|
@ -1215,7 +1213,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
maybeCallBeforeSave(replacement, mappedReplacement, collectionName); |
|
|
|
maybeCallBeforeSave(replacement, mappedReplacement, collectionName); |
|
|
|
|
|
|
|
|
|
|
|
R saved = doFindAndReplace(collectionPreparer, collectionName, mappedQuery, mappedFields, mappedSort, |
|
|
|
R saved = doFindAndReplace(collectionPreparer, collectionName, mappedQuery, mappedFields, mappedSort, |
|
|
|
queryContext.getCollation(entityType).orElse(null), entityType, mappedReplacement, options, projection, resultConverter); |
|
|
|
queryContext.getCollation(entityType).orElse(null), entityType, mappedReplacement, options, projection, |
|
|
|
|
|
|
|
resultConverter); |
|
|
|
|
|
|
|
|
|
|
|
if (saved != null) { |
|
|
|
if (saved != null) { |
|
|
|
maybeEmitEvent(new AfterSaveEvent<>(saved, mappedReplacement, collectionName)); |
|
|
|
maybeEmitEvent(new AfterSaveEvent<>(saved, mappedReplacement, collectionName)); |
|
|
|
@ -2221,8 +2220,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
List<T> result = doFind(collectionName, createDelegate(query), query.getQueryObject(), query.getFieldsObject(), entityClass, |
|
|
|
List<T> result = doFind(collectionName, createDelegate(query), query.getQueryObject(), query.getFieldsObject(), |
|
|
|
new QueryCursorPreparer(query, entityClass), callback); |
|
|
|
entityClass, new QueryCursorPreparer(query, entityClass), callback); |
|
|
|
|
|
|
|
|
|
|
|
if (!CollectionUtils.isEmpty(result)) { |
|
|
|
if (!CollectionUtils.isEmpty(result)) { |
|
|
|
|
|
|
|
|
|
|
|
@ -2278,8 +2277,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
if (aggregation instanceof TypedAggregation<?> ta && outputType.isInterface()) { |
|
|
|
if (aggregation instanceof TypedAggregation<?> ta && outputType.isInterface()) { |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(outputType, ta.getInputType()); |
|
|
|
EntityProjection<T, ?> projection = operations.introspectProjection(outputType, ta.getInputType()); |
|
|
|
ProjectingReadCallback cb = new ProjectingReadCallback(mongoConverter, projection, collectionName); |
|
|
|
ProjectingReadCallback cb = new ProjectingReadCallback(mongoConverter, projection, collectionName); |
|
|
|
callback = new QueryResultConverterCallback<>(resultConverter, |
|
|
|
callback = new QueryResultConverterCallback<>(resultConverter, cb); |
|
|
|
cb); |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
callback = new QueryResultConverterCallback<>(resultConverter, |
|
|
|
callback = new QueryResultConverterCallback<>(resultConverter, |
|
|
|
@ -2370,8 +2368,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
@SuppressWarnings({ "ConstantConditions", "NullAway" }) |
|
|
|
<T, O> Stream<O> doAggregateStream(Aggregation aggregation, String collectionName, Class<T> outputType, |
|
|
|
<T, O> Stream<O> doAggregateStream(Aggregation aggregation, String collectionName, Class<T> outputType, |
|
|
|
QueryResultConverter<? super T, ? extends O> resultConverter, |
|
|
|
QueryResultConverter<? super T, ? extends O> resultConverter, @Nullable AggregationOperationContext context) { |
|
|
|
@Nullable AggregationOperationContext context) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Assert.notNull(aggregation, "Aggregation pipeline must not be null"); |
|
|
|
Assert.notNull(aggregation, "Aggregation pipeline must not be null"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
Assert.hasText(collectionName, "Collection name must not be null or empty"); |
|
|
|
@ -2649,9 +2646,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
* @return the converted object or {@literal null} if none exists. |
|
|
|
* @return the converted object or {@literal null} if none exists. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
protected <T> T doFindOne(String collectionName, |
|
|
|
protected <T> T doFindOne(String collectionName, CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
CollectionPreparer<MongoCollection<Document>> collectionPreparer, Document query, Document fields, |
|
|
|
Document query, Document fields, Class<T> entityClass) { |
|
|
|
Class<T> entityClass) { |
|
|
|
|
|
|
|
return doFindOne(collectionName, collectionPreparer, query, fields, CursorPreparer.NO_OP_PREPARER, entityClass); |
|
|
|
return doFindOne(collectionName, collectionPreparer, query, fields, CursorPreparer.NO_OP_PREPARER, entityClass); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -2670,9 +2666,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
protected <T> T doFindOne(String collectionName, |
|
|
|
protected <T> T doFindOne(String collectionName, CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
CollectionPreparer<MongoCollection<Document>> collectionPreparer, Document query, Document fields, |
|
|
|
Document query, Document fields, CursorPreparer preparer, Class<T> entityClass) { |
|
|
|
CursorPreparer preparer, Class<T> entityClass) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass); |
|
|
|
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(entityClass); |
|
|
|
|
|
|
|
|
|
|
|
@ -2870,9 +2865,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
@SuppressWarnings("ConstantConditions") |
|
|
|
<S, T> @Nullable T doFindAndModify(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
<S, T> @Nullable T doFindAndModify(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
String collectionName, |
|
|
|
String collectionName, Document query, @Nullable Document fields, @Nullable Document sort, Class<S> entityClass, |
|
|
|
Document query, @Nullable Document fields, @Nullable Document sort, Class<S> entityClass, UpdateDefinition update, |
|
|
|
UpdateDefinition update, @Nullable FindAndModifyOptions options, |
|
|
|
@Nullable FindAndModifyOptions options, QueryResultConverter<? super S, ? extends T> resultConverter) { |
|
|
|
QueryResultConverter<? super S, ? extends T> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
if (options == null) { |
|
|
|
if (options == null) { |
|
|
|
options = new FindAndModifyOptions(); |
|
|
|
options = new FindAndModifyOptions(); |
|
|
|
@ -2894,7 +2889,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
serializeToJsonSafely(mappedUpdate), collectionName)); |
|
|
|
serializeToJsonSafely(mappedUpdate), collectionName)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<T> callback = getResultReader(EntityProjection.nonProjecting(entityClass), collectionName, resultConverter); |
|
|
|
DocumentCallback<T> callback = getResultReader(EntityProjection.nonProjecting(entityClass), collectionName, |
|
|
|
|
|
|
|
resultConverter); |
|
|
|
|
|
|
|
|
|
|
|
return executeFindOneInternal( |
|
|
|
return executeFindOneInternal( |
|
|
|
new FindAndModifyCallback(collectionPreparer, mappedQuery, fields, sort, mappedUpdate, |
|
|
|
new FindAndModifyCallback(collectionPreparer, mappedQuery, fields, sort, mappedUpdate, |
|
|
|
@ -2919,8 +2915,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
protected <S, T> T doFindAndReplace(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
protected <S, T> T doFindAndReplace(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
String collectionName, |
|
|
|
String collectionName, Document mappedQuery, Document mappedFields, Document mappedSort, |
|
|
|
Document mappedQuery, Document mappedFields, Document mappedSort, |
|
|
|
|
|
|
|
com.mongodb.client.model.@Nullable Collation collation, Class<S> entityType, Document replacement, |
|
|
|
com.mongodb.client.model.@Nullable Collation collation, Class<S> entityType, Document replacement, |
|
|
|
FindAndReplaceOptions options, Class<T> resultType) { |
|
|
|
FindAndReplaceOptions options, Class<T> resultType) { |
|
|
|
|
|
|
|
|
|
|
|
@ -2963,10 +2958,10 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@Nullable |
|
|
|
@Nullable |
|
|
|
private <S, T, R> R doFindAndReplace(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
private <S, T, R> R doFindAndReplace(CollectionPreparer<MongoCollection<Document>> collectionPreparer, |
|
|
|
String collectionName, |
|
|
|
String collectionName, Document mappedQuery, Document mappedFields, Document mappedSort, |
|
|
|
Document mappedQuery, Document mappedFields, Document mappedSort, |
|
|
|
|
|
|
|
com.mongodb.client.model.@Nullable Collation collation, Class<T> entityType, Document replacement, |
|
|
|
com.mongodb.client.model.@Nullable Collation collation, Class<T> entityType, Document replacement, |
|
|
|
FindAndReplaceOptions options, EntityProjection<S, T> projection, QueryResultConverter<? super S, ? extends R> resultConverter) { |
|
|
|
FindAndReplaceOptions options, EntityProjection<S, T> projection, |
|
|
|
|
|
|
|
QueryResultConverter<? super S, ? extends R> resultConverter) { |
|
|
|
|
|
|
|
|
|
|
|
if (LOGGER.isDebugEnabled()) { |
|
|
|
if (LOGGER.isDebugEnabled()) { |
|
|
|
LOGGER |
|
|
|
LOGGER |
|
|
|
@ -2979,8 +2974,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
|
|
|
|
|
|
|
|
DocumentCallback<R> callback = getResultReader(projection, collectionName, resultConverter); |
|
|
|
DocumentCallback<R> callback = getResultReader(projection, collectionName, resultConverter); |
|
|
|
return executeFindOneInternal(new FindAndReplaceCallback(collectionPreparer, mappedQuery, mappedFields, mappedSort, |
|
|
|
return executeFindOneInternal(new FindAndReplaceCallback(collectionPreparer, mappedQuery, mappedFields, mappedSort, |
|
|
|
replacement, collation, options),callback, |
|
|
|
replacement, collation, options), callback, collectionName); |
|
|
|
collectionName); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("NullAway") |
|
|
|
@SuppressWarnings("NullAway") |
|
|
|
@ -3158,8 +3152,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware, |
|
|
|
return getMappedSortObject(sortObject, mappingContext.getPersistentEntity(type)); |
|
|
|
return getMappedSortObject(sortObject, mappingContext.getPersistentEntity(type)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private @Nullable Document getMappedSortObject(@Nullable Document sortObject, |
|
|
|
private @Nullable Document getMappedSortObject(@Nullable Document sortObject, @Nullable MongoPersistentEntity<?> entity) { |
|
|
|
@Nullable MongoPersistentEntity<?> entity) { |
|
|
|
|
|
|
|
|
|
|
|
if (ObjectUtils.isEmpty(sortObject)) { |
|
|
|
if (ObjectUtils.isEmpty(sortObject)) { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|