Prevent key extraction if a keyset value is null.
Follow the changes in data commons that renamed scroll to window. Also error when a certain scroll position does not allow creating a query out of it because of null values. See: #4308 Original Pull Request: #4317
This commit is contained in:
@@ -21,6 +21,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.bson.BsonNull;
|
||||
import org.bson.Document;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
@@ -471,6 +472,7 @@ class EntityOperations {
|
||||
* @param sortObject
|
||||
* @return
|
||||
* @since 3.1
|
||||
* @throws IllegalStateException if a sort key yields {@literal null}.
|
||||
*/
|
||||
Map<String, Object> extractKeys(Document sortObject);
|
||||
|
||||
@@ -600,7 +602,14 @@ class EntityOperations {
|
||||
keyset.put(ID_FIELD, getId());
|
||||
|
||||
for (String key : sortObject.keySet()) {
|
||||
keyset.put(key, BsonUtils.resolveValue(map, key));
|
||||
Object value = BsonUtils.resolveValue(map, key);
|
||||
|
||||
if (value == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Cannot extract value for key %s because its value is null", key));
|
||||
}
|
||||
|
||||
keyset.put(key, value);
|
||||
}
|
||||
|
||||
return keyset;
|
||||
@@ -756,14 +765,22 @@ class EntityOperations {
|
||||
|
||||
for (String key : sortObject.keySet()) {
|
||||
|
||||
Object value;
|
||||
if (key.indexOf('.') != -1) {
|
||||
|
||||
// follow the path across nested levels.
|
||||
// TODO: We should have a MongoDB-specific property path abstraction to allow diving into Document.
|
||||
keyset.put(key, getNestedPropertyValue(key));
|
||||
value = getNestedPropertyValue(key);
|
||||
} else {
|
||||
keyset.put(key, getPropertyValue(key));
|
||||
value = getPropertyValue(key);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Cannot extract value for key %s because its value is null", key));
|
||||
}
|
||||
|
||||
keyset.put(key, value);
|
||||
}
|
||||
|
||||
return keyset;
|
||||
@@ -774,7 +791,7 @@ class EntityOperations {
|
||||
|
||||
String[] segments = key.split("\\.");
|
||||
Entity<?> currentEntity = this;
|
||||
Object currentValue = null;
|
||||
Object currentValue = BsonNull.VALUE;
|
||||
|
||||
for (int i = 0; i < segments.length; i++) {
|
||||
|
||||
@@ -786,7 +803,7 @@ class EntityOperations {
|
||||
}
|
||||
}
|
||||
|
||||
return currentValue;
|
||||
return currentValue != null ? currentValue : BsonNull.VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||
@@ -126,16 +126,17 @@ public interface ExecutableFindOperation {
|
||||
Stream<T> stream();
|
||||
|
||||
/**
|
||||
* Return a scroll of elements either starting or resuming at
|
||||
* Return a window of elements either starting or resuming at
|
||||
* {@link org.springframework.data.domain.ScrollPosition}.
|
||||
*
|
||||
* @param scrollPosition the scroll position.
|
||||
* @return a scroll of the resulting elements.
|
||||
* @return a window of the resulting elements.
|
||||
* @throws IllegalStateException if a potential {@literal KeysetScrollPosition} contains an invalid position.
|
||||
* @since 4.1
|
||||
* @see org.springframework.data.domain.OffsetScrollPosition
|
||||
* @see org.springframework.data.domain.KeysetScrollPosition
|
||||
*/
|
||||
Scroll<T> scroll(ScrollPosition scrollPosition);
|
||||
Window<T> scroll(ScrollPosition scrollPosition);
|
||||
|
||||
/**
|
||||
* Get the number of matching elements. <br />
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -141,7 +141,7 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scroll<T> scroll(ScrollPosition scrollPosition) {
|
||||
public Window<T> scroll(ScrollPosition scrollPosition) {
|
||||
return template.doScroll(query.with(scrollPosition), domainType, returnType, getCollectionName());
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.mongodb.core.BulkOperations.BulkMode;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
@@ -807,7 +807,7 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
<T> List<T> find(Query query, Class<T> entityClass, String collectionName);
|
||||
|
||||
/**
|
||||
* Query for a scroll window of objects of type T from the specified collection. <br />
|
||||
* Query for a window window of objects of type T from the specified collection. <br />
|
||||
* Make sure to either set {@link Query#skip(long)} or {@link Query#with(KeysetScrollPosition)} along with
|
||||
* {@link Query#limit(int)} to limit large query results for efficient scrolling. <br />
|
||||
* Result objects are converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||
@@ -817,16 +817,17 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification. Must not be {@literal null}.
|
||||
* @param entityType the parametrized type of the returned list.
|
||||
* @return the converted scroll.
|
||||
* @param entityType the parametrized type of the returned window.
|
||||
* @return the converted window.
|
||||
* @throws IllegalStateException if a potential {@link Query#getKeyset() KeysetScrollPosition} contains an invalid position.
|
||||
* @since 4.1
|
||||
* @see Query#with(org.springframework.data.domain.OffsetScrollPosition)
|
||||
* @see Query#with(org.springframework.data.domain.KeysetScrollPosition)
|
||||
*/
|
||||
<T> Scroll<T> scroll(Query query, Class<T> entityType);
|
||||
<T> Window<T> scroll(Query query, Class<T> entityType);
|
||||
|
||||
/**
|
||||
* Query for a scroll of objects of type T from the specified collection. <br />
|
||||
* Query for a window of objects of type T from the specified collection. <br />
|
||||
* Make sure to either set {@link Query#skip(long)} or {@link Query#with(KeysetScrollPosition)} along with
|
||||
* {@link Query#limit(int)} to limit large query results for efficient scrolling. <br />
|
||||
* Result objects are converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||
@@ -836,14 +837,15 @@ public interface MongoOperations extends FluentMongoOperations {
|
||||
*
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification. Must not be {@literal null}.
|
||||
* @param entityType the parametrized type of the returned list.
|
||||
* @param entityType the parametrized type of the returned window.
|
||||
* @param collectionName name of the collection to retrieve the objects from.
|
||||
* @return the converted scroll.
|
||||
* @return the converted window.
|
||||
* @throws IllegalStateException if a potential {@link Query#getKeyset() KeysetScrollPosition} contains an invalid position.
|
||||
* @since 4.1
|
||||
* @see Query#with(org.springframework.data.domain.OffsetScrollPosition)
|
||||
* @see Query#with(org.springframework.data.domain.KeysetScrollPosition)
|
||||
*/
|
||||
<T> Scroll<T> scroll(Query query, Class<T> entityType, String collectionName);
|
||||
<T> Window<T> scroll(Query query, Class<T> entityType, String collectionName);
|
||||
|
||||
/**
|
||||
* Returns a document with the given id mapped onto the given class. The collection the query is ran against will be
|
||||
|
||||
@@ -45,7 +45,7 @@ import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
@@ -66,7 +66,7 @@ import org.springframework.data.mongodb.core.QueryOperations.DeleteContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.DistinctQueryContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.QueryContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.UpdateContext;
|
||||
import org.springframework.data.mongodb.core.ScrollUtils.KeySetCursorQuery;
|
||||
import org.springframework.data.mongodb.core.ScrollUtils.KeySetScrollQuery;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
@@ -851,7 +851,7 @@ public class MongoTemplate
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Scroll<T> scroll(Query query, Class<T> entityType) {
|
||||
public <T> Window<T> scroll(Query query, Class<T> entityType) {
|
||||
|
||||
Assert.notNull(entityType, "Entity type must not be null");
|
||||
|
||||
@@ -859,11 +859,11 @@ public class MongoTemplate
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Scroll<T> scroll(Query query, Class<T> entityType, String collectionName) {
|
||||
public <T> Window<T> scroll(Query query, Class<T> entityType, String collectionName) {
|
||||
return doScroll(query, entityType, entityType, collectionName);
|
||||
}
|
||||
|
||||
<T> Scroll<T> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, String collectionName) {
|
||||
<T> Window<T> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
@@ -875,7 +875,7 @@ public class MongoTemplate
|
||||
|
||||
if (query.hasKeyset()) {
|
||||
|
||||
KeySetCursorQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query,
|
||||
KeySetScrollQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query,
|
||||
operations.getIdPropertyName(sourceClass));
|
||||
|
||||
List<T> result = doFind(collectionName, createDelegate(query), keysetPaginationQuery.query(),
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.data.mongodb.core;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||
@@ -98,7 +98,7 @@ public interface ReactiveFindOperation {
|
||||
* @see org.springframework.data.domain.OffsetScrollPosition
|
||||
* @see org.springframework.data.domain.KeysetScrollPosition
|
||||
*/
|
||||
Mono<Scroll<T>> scroll(ScrollPosition scrollPosition);
|
||||
Mono<Window<T>> scroll(ScrollPosition scrollPosition);
|
||||
|
||||
/**
|
||||
* Get all matching elements using a {@link com.mongodb.CursorType#TailableAwait tailable cursor}. The stream will
|
||||
|
||||
@@ -20,7 +20,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.mongodb.core.CollectionPreparerSupport.ReactiveCollectionPreparerDelegate;
|
||||
import org.springframework.data.mongodb.core.query.NearQuery;
|
||||
@@ -140,7 +140,7 @@ class ReactiveFindOperationSupport implements ReactiveFindOperation {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Scroll<T>> scroll(ScrollPosition scrollPosition) {
|
||||
public Mono<Window<T>> scroll(ScrollPosition scrollPosition) {
|
||||
return template.doScroll(query.with(scrollPosition), domainType, returnType, getCollectionName());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.bson.Document;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.reactivestreams.Subscription;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
@@ -477,15 +477,16 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
* @param query the query class that specifies the criteria used to find a record and also an optional fields
|
||||
* specification. Must not be {@literal null}.
|
||||
* @param entityType the parametrized type of the returned list.
|
||||
* @return {@link Mono} emitting the converted scroll.
|
||||
* @return {@link Mono} emitting the converted window.
|
||||
* @throws IllegalStateException if a potential {@link Query#getKeyset() KeysetScrollPosition} contains an invalid position.
|
||||
* @since 4.1
|
||||
* @see Query#with(org.springframework.data.domain.OffsetScrollPosition)
|
||||
* @see Query#with(org.springframework.data.domain.KeysetScrollPosition)
|
||||
*/
|
||||
<T> Mono<Scroll<T>> scroll(Query query, Class<T> entityType);
|
||||
<T> Mono<Window<T>> scroll(Query query, Class<T> entityType);
|
||||
|
||||
/**
|
||||
* Query for a scroll of objects of type T from the specified collection. <br />
|
||||
* Query for a window of objects of type T from the specified collection. <br />
|
||||
* Make sure to either set {@link Query#skip(long)} or {@link Query#with(KeysetScrollPosition)} along with
|
||||
* {@link Query#limit(int)} to limit large query results for efficient scrolling. <br />
|
||||
* Result objects are converted from the MongoDB native representation using an instance of {@see MongoConverter}.
|
||||
@@ -497,12 +498,13 @@ public interface ReactiveMongoOperations extends ReactiveFluentMongoOperations {
|
||||
* specification. Must not be {@literal null}.
|
||||
* @param entityType the parametrized type of the returned list.
|
||||
* @param collectionName name of the collection to retrieve the objects from.
|
||||
* @return {@link Mono} emitting the converted scroll window.
|
||||
* @return {@link Mono} emitting the converted window.
|
||||
* @throws IllegalStateException if a potential {@link Query#getKeyset() KeysetScrollPosition} contains an invalid position.
|
||||
* @since 4.1
|
||||
* @see Query#with(org.springframework.data.domain.OffsetScrollPosition)
|
||||
* @see Query#with(org.springframework.data.domain.KeysetScrollPosition)
|
||||
*/
|
||||
<T> Mono<Scroll<T>> scroll(Query query, Class<T> entityType, String collectionName);
|
||||
<T> Mono<Window<T>> scroll(Query query, Class<T> entityType, String collectionName);
|
||||
|
||||
/**
|
||||
* Returns a document with the given id mapped onto the given class. The collection the query is ran against will be
|
||||
|
||||
@@ -59,7 +59,7 @@ import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.dao.support.PersistenceExceptionTranslator;
|
||||
import org.springframework.data.convert.EntityReader;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.Metric;
|
||||
@@ -80,7 +80,7 @@ import org.springframework.data.mongodb.core.QueryOperations.DeleteContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.DistinctQueryContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.QueryContext;
|
||||
import org.springframework.data.mongodb.core.QueryOperations.UpdateContext;
|
||||
import org.springframework.data.mongodb.core.ScrollUtils.KeySetCursorQuery;
|
||||
import org.springframework.data.mongodb.core.ScrollUtils.KeySetScrollQuery;
|
||||
import org.springframework.data.mongodb.core.aggregation.Aggregation;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
|
||||
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
|
||||
@@ -830,7 +830,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<Scroll<T>> scroll(Query query, Class<T> entityType) {
|
||||
public <T> Mono<Window<T>> scroll(Query query, Class<T> entityType) {
|
||||
|
||||
Assert.notNull(entityType, "Entity type must not be null");
|
||||
|
||||
@@ -838,11 +838,11 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Mono<Scroll<T>> scroll(Query query, Class<T> entityType, String collectionName) {
|
||||
public <T> Mono<Window<T>> scroll(Query query, Class<T> entityType, String collectionName) {
|
||||
return doScroll(query, entityType, entityType, collectionName);
|
||||
}
|
||||
|
||||
<T> Mono<Scroll<T>> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, String collectionName) {
|
||||
<T> Mono<Window<T>> doScroll(Query query, Class<?> sourceClass, Class<T> targetClass, String collectionName) {
|
||||
|
||||
Assert.notNull(query, "Query must not be null");
|
||||
Assert.notNull(collectionName, "CollectionName must not be null");
|
||||
@@ -853,7 +853,7 @@ public class ReactiveMongoTemplate implements ReactiveMongoOperations, Applicati
|
||||
|
||||
if (query.hasKeyset()) {
|
||||
|
||||
KeySetCursorQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query,
|
||||
KeySetScrollQuery keysetPaginationQuery = ScrollUtils.createKeysetPaginationQuery(query,
|
||||
operations.getIdPropertyName(sourceClass));
|
||||
|
||||
Mono<List<T>> result = doFind(collectionName, ReactiveCollectionPreparerDelegate.of(query),
|
||||
|
||||
@@ -20,17 +20,19 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.IntFunction;
|
||||
|
||||
import org.bson.BsonNull;
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.mongodb.core.EntityOperations.Entity;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
|
||||
/**
|
||||
* Utilities to run scroll queries and create {@link Scroll} results.
|
||||
* Utilities to run scroll queries and create {@link Window} results.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 4.1
|
||||
*/
|
||||
class ScrollUtils {
|
||||
@@ -42,7 +44,7 @@ class ScrollUtils {
|
||||
* @param idPropertyName
|
||||
* @return
|
||||
*/
|
||||
static KeySetCursorQuery createKeysetPaginationQuery(Query query, String idPropertyName) {
|
||||
static KeySetScrollQuery createKeysetPaginationQuery(Query query, String idPropertyName) {
|
||||
|
||||
Document sortObject = query.isSorted() ? query.getSortObject() : new Document();
|
||||
sortObject.put(idPropertyName, 1);
|
||||
@@ -84,6 +86,9 @@ class ScrollUtils {
|
||||
Object o = keysetValues.get(sortSegment);
|
||||
|
||||
if (j >= i) { // tail segment
|
||||
if(o instanceof BsonNull) {
|
||||
throw new IllegalStateException("Cannot resume from KeysetScrollPosition. Offending key: '%s' is 'null'".formatted(sortSegment));
|
||||
}
|
||||
sortConstraint.put(sortSegment, new Document(sortOrder == 1 ? "$gt" : "$lt", o));
|
||||
break;
|
||||
}
|
||||
@@ -104,10 +109,10 @@ class ScrollUtils {
|
||||
queryObject.put("$or", or);
|
||||
}
|
||||
|
||||
return new KeySetCursorQuery(queryObject, fieldsObject, sortObject);
|
||||
return new KeySetScrollQuery(queryObject, fieldsObject, sortObject);
|
||||
}
|
||||
|
||||
static <T> Scroll<T> createWindow(Document sortObject, int limit, List<T> result, EntityOperations operations) {
|
||||
static <T> Window<T> createWindow(Document sortObject, int limit, List<T> result, EntityOperations operations) {
|
||||
|
||||
IntFunction<KeysetScrollPosition> positionFunction = value -> {
|
||||
|
||||
@@ -121,8 +126,8 @@ class ScrollUtils {
|
||||
return createWindow(result, limit, positionFunction);
|
||||
}
|
||||
|
||||
static <T> Scroll<T> createWindow(List<T> result, int limit, IntFunction<? extends ScrollPosition> positionFunction) {
|
||||
return Scroll.from(getSubList(result, limit), positionFunction, hasMoreElements(result, limit));
|
||||
static <T> Window<T> createWindow(List<T> result, int limit, IntFunction<? extends ScrollPosition> positionFunction) {
|
||||
return Window.from(getSubList(result, limit), positionFunction, hasMoreElements(result, limit));
|
||||
}
|
||||
|
||||
static boolean hasMoreElements(List<?> result, int limit) {
|
||||
@@ -138,7 +143,7 @@ class ScrollUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
record KeySetCursorQuery(Document query, Document fields, Document sort) {
|
||||
record KeySetScrollQuery(Document query, Document fields, Document sort) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.bson.Document;
|
||||
import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
@@ -259,7 +259,7 @@ public class QuerydslMongoPredicateExecutor<T> extends QuerydslPredicateExecutor
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scroll<T> scroll(ScrollPosition scrollPosition) {
|
||||
public Window<T> scroll(ScrollPosition scrollPosition) {
|
||||
return createQuery().scroll(scrollPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.bson.Document;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||
@@ -227,7 +227,7 @@ public class ReactiveQuerydslMongoPredicateExecutor<T> extends QuerydslPredicate
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Scroll<T>> scroll(ScrollPosition scrollPosition) {
|
||||
public Mono<Window<T>> scroll(ScrollPosition scrollPosition) {
|
||||
return createQuery().scroll(scrollPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.function.Consumer;
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
import org.springframework.data.mongodb.core.ReactiveFindOperation;
|
||||
@@ -91,7 +91,7 @@ class ReactiveSpringDataMongodbQuery<K> extends SpringDataMongodbQuerySupport<Re
|
||||
return createQuery().flatMapMany(it -> find.matching(it).all());
|
||||
}
|
||||
|
||||
Mono<Scroll<K>> scroll(ScrollPosition scrollPosition) {
|
||||
Mono<Window<K>> scroll(ScrollPosition scrollPosition) {
|
||||
return createQuery().flatMap(it -> find.matching(it).scroll(scrollPosition));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.ExecutableFindOperation;
|
||||
@@ -392,7 +392,7 @@ public class SimpleMongoRepository<T, ID> implements MongoRepository<T, ID> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scroll<T> scroll(ScrollPosition scrollPosition) {
|
||||
public Window<T> scroll(ScrollPosition scrollPosition) {
|
||||
return createQuery().scroll(scrollPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.domain.Example;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.ReactiveFindOperation;
|
||||
@@ -436,7 +436,7 @@ public class SimpleReactiveMongoRepository<T, ID extends Serializable> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Scroll<T>> scroll(ScrollPosition scrollPosition) {
|
||||
public Mono<Window<T>> scroll(ScrollPosition scrollPosition) {
|
||||
return createQuery().scroll(scrollPosition);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.bson.Document;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.mongodb.core.ExecutableFindOperation;
|
||||
import org.springframework.data.mongodb.core.MongoOperations;
|
||||
@@ -133,12 +133,12 @@ public class SpringDataMongodbQuery<T> extends SpringDataMongodbQuerySupport<Spr
|
||||
}
|
||||
}
|
||||
|
||||
public Scroll<T> scroll(ScrollPosition scrollPosition) {
|
||||
public Window<T> scroll(ScrollPosition scrollPosition) {
|
||||
|
||||
try {
|
||||
return find.matching(createQuery()).scroll(scrollPosition);
|
||||
} catch (RuntimeException e) {
|
||||
return handleException(e, Scroll.from(Collections.emptyList(), value -> {
|
||||
return handleException(e, Window.from(Collections.emptyList(), value -> {
|
||||
throw new UnsupportedOperationException();
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ import org.springframework.data.annotation.PersistenceCreator;
|
||||
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.mongodb.core.MongoTemplateTests.PersonWithIdPropertyOfTypeUUIDListener;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -51,9 +51,10 @@ import org.springframework.data.mongodb.test.util.MongoTestTemplate;
|
||||
import com.mongodb.client.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link Scroll} queries.
|
||||
* Integration tests for {@link org.springframework.data.domain.Window} queries.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@ExtendWith(MongoClientExtension.class)
|
||||
class MongoTemplateScrollTests {
|
||||
@@ -94,7 +95,7 @@ class MongoTemplateScrollTests {
|
||||
template.remove(WithNestedDocument.class).all();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test // GH-4308
|
||||
void shouldUseKeysetScrollingWithNestedSort() {
|
||||
|
||||
WithNestedDocument john20 = new WithNestedDocument(null, "John", 120, new WithNestedDocument("John", 20),
|
||||
@@ -110,20 +111,55 @@ class MongoTemplateScrollTests {
|
||||
.limit(2);
|
||||
q.with(KeysetScrollPosition.initial());
|
||||
|
||||
Scroll<WithNestedDocument> scroll = template.scroll(q, WithNestedDocument.class);
|
||||
Window<WithNestedDocument> scroll = template.scroll(q, WithNestedDocument.class);
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
assertThat(scroll).hasSize(2);
|
||||
assertThat(scroll).containsOnly(john20, john40);
|
||||
|
||||
scroll = template.scroll(q.with(scroll.lastPosition()), WithNestedDocument.class);
|
||||
scroll = template.scroll(q.with(scroll.positionAt(scroll.size()-1)), WithNestedDocument.class);
|
||||
|
||||
assertThat(scroll.hasNext()).isFalse();
|
||||
assertThat(scroll.isLast()).isTrue();
|
||||
assertThat(scroll).hasSize(1);
|
||||
assertThat(scroll).containsOnly(john41);
|
||||
}
|
||||
|
||||
@Test // GH-4308
|
||||
void shouldErrorOnNullValueForQuery() {
|
||||
|
||||
WithNestedDocument john20 = new WithNestedDocument(null, "John", 120, new WithNestedDocument("John", 20),
|
||||
new Document("name", "bar"));
|
||||
WithNestedDocument john40 = new WithNestedDocument(null, "John", 140, new WithNestedDocument("John", 41),
|
||||
new Document());
|
||||
WithNestedDocument john41 = new WithNestedDocument(null, "John", 140, new WithNestedDocument("John", 41),
|
||||
new Document());
|
||||
WithNestedDocument john42 = new WithNestedDocument(null, "John", 140, new WithNestedDocument("John", 41),
|
||||
new Document());
|
||||
WithNestedDocument john43 = new WithNestedDocument(null, "John", 140, new WithNestedDocument("John", 41),
|
||||
new Document());
|
||||
WithNestedDocument john44 = new WithNestedDocument(null, "John", 141, new WithNestedDocument("John", 41),
|
||||
new Document("name", "foo"));
|
||||
|
||||
template.insertAll(Arrays.asList(john20, john40, john41, john42, john43, john44));
|
||||
|
||||
Query q = new Query(where("name").regex("J.*")).with(Sort.by("nested.name", "nested.age", "document.name"))
|
||||
.limit(2);
|
||||
q.with(KeysetScrollPosition.initial());
|
||||
|
||||
Window<WithNestedDocument> scroll = template.scroll(q, WithNestedDocument.class);
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
assertThat(scroll).hasSize(2);
|
||||
assertThat(scroll).containsOnly(john20, john40);
|
||||
|
||||
ScrollPosition startAfter = scroll.positionAt(scroll.size()-1);
|
||||
|
||||
assertThatExceptionOfType(IllegalStateException.class)
|
||||
.isThrownBy(() -> template.scroll(q.with(startAfter), WithNestedDocument.class))
|
||||
.withMessageContaining("document.name");
|
||||
}
|
||||
|
||||
@ParameterizedTest // GH-4308
|
||||
@@ -142,14 +178,14 @@ class MongoTemplateScrollTests {
|
||||
Query q = new Query(where("firstName").regex("J.*")).with(Sort.by("firstName", "age")).limit(2);
|
||||
q.with(scrollPosition);
|
||||
|
||||
Scroll<T> scroll = template.scroll(q, resultType, "person");
|
||||
Window<T> scroll = template.scroll(q, resultType, "person");
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
assertThat(scroll).hasSize(2);
|
||||
assertThat(scroll).containsOnly(assertionConverter.apply(jane_20), assertionConverter.apply(jane_40));
|
||||
|
||||
scroll = template.scroll(q.with(scroll.lastPosition()).limit(3), resultType, "person");
|
||||
scroll = template.scroll(q.with(scroll.positionAt(scroll.size()-1)).limit(3), resultType, "person");
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
@@ -157,7 +193,7 @@ class MongoTemplateScrollTests {
|
||||
assertThat(scroll).contains(assertionConverter.apply(jane_42), assertionConverter.apply(john20));
|
||||
assertThat(scroll).containsAnyOf(assertionConverter.apply(john40_1), assertionConverter.apply(john40_2));
|
||||
|
||||
scroll = template.scroll(q.with(scroll.lastPosition()).limit(1), resultType, "person");
|
||||
scroll = template.scroll(q.with(scroll.positionAt(scroll.size()-1)).limit(1), resultType, "person");
|
||||
|
||||
assertThat(scroll.hasNext()).isFalse();
|
||||
assertThat(scroll.isLast()).isTrue();
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.OffsetScrollPosition;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
@@ -46,7 +46,7 @@ import org.springframework.data.mongodb.test.util.ReactiveMongoTestTemplate;
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link Scroll} queries.
|
||||
* Integration tests for {@link Window} queries.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@@ -100,14 +100,14 @@ class ReactiveMongoTemplateScrollTests {
|
||||
Query q = new Query(where("firstName").regex("J.*")).with(Sort.by("firstName", "age")).limit(2);
|
||||
q.with(scrollPosition);
|
||||
|
||||
Scroll<T> scroll = template.scroll(q, resultType, "person").block(Duration.ofSeconds(10));
|
||||
Window<T> scroll = template.scroll(q, resultType, "person").block(Duration.ofSeconds(10));
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
assertThat(scroll).hasSize(2);
|
||||
assertThat(scroll).containsOnly(assertionConverter.apply(jane_20), assertionConverter.apply(jane_40));
|
||||
|
||||
scroll = template.scroll(q.limit(3).with(scroll.lastPosition()), resultType, "person")
|
||||
scroll = template.scroll(q.limit(3).with(scroll.positionAt(scroll.size() - 1)), resultType, "person")
|
||||
.block(Duration.ofSeconds(10));
|
||||
|
||||
assertThat(scroll.hasNext()).isTrue();
|
||||
@@ -116,7 +116,7 @@ class ReactiveMongoTemplateScrollTests {
|
||||
assertThat(scroll).contains(assertionConverter.apply(jane_42), assertionConverter.apply(john20));
|
||||
assertThat(scroll).containsAnyOf(assertionConverter.apply(john40_1), assertionConverter.apply(john40_2));
|
||||
|
||||
scroll = template.scroll(q.limit(1).with(scroll.lastPosition()), resultType, "person")
|
||||
scroll = template.scroll(q.limit(1).with(scroll.positionAt(scroll.size() - 1)), resultType, "person")
|
||||
.block(Duration.ofSeconds(10));
|
||||
|
||||
assertThat(scroll.hasNext()).isFalse();
|
||||
|
||||
@@ -205,7 +205,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
|
||||
@Test // GH-4308
|
||||
void appliesScrollPositionCorrectly() {
|
||||
|
||||
Scroll<Person> page = repository.findTop2ByLastnameLikeOrderByLastnameAscFirstnameAsc("*a*",
|
||||
Window<Person> page = repository.findTop2ByLastnameLikeOrderByLastnameAscFirstnameAsc("*a*",
|
||||
KeysetScrollPosition.initial());
|
||||
|
||||
assertThat(page.isLast()).isFalse();
|
||||
@@ -216,7 +216,7 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
|
||||
@Test // GH-4308
|
||||
void appliesScrollPositionWithProjectionCorrectly() {
|
||||
|
||||
Scroll<PersonSummaryDto> page = repository.findCursorProjectionByLastnameLike("*a*",
|
||||
Window<PersonSummaryDto> page = repository.findCursorProjectionByLastnameLike("*a*",
|
||||
PageRequest.of(0, 2, Sort.by(Direction.ASC, "lastname", "firstname")));
|
||||
|
||||
assertThat(page.isLast()).isFalse();
|
||||
@@ -956,12 +956,12 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
|
||||
@Test // DATAMONGO-969
|
||||
void shouldScrollPersonsWhenUsingQueryDslPerdicatedOnIdProperty() {
|
||||
|
||||
Scroll<Person> scroll = repository.findBy(person.id.in(asList(dave.id, carter.id, boyd.id)), //
|
||||
Window<Person> scroll = repository.findBy(person.id.in(asList(dave.id, carter.id, boyd.id)), //
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(KeysetScrollPosition.initial()));
|
||||
|
||||
assertThat(scroll).containsExactly(boyd, carter);
|
||||
|
||||
ScrollPosition resumeFrom = scroll.lastPosition();
|
||||
ScrollPosition resumeFrom = scroll.positionAt(scroll.size() - 1);
|
||||
scroll = repository.findBy(person.id.in(asList(dave.id, carter.id, boyd.id)), //
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(resumeFrom));
|
||||
|
||||
@@ -1185,14 +1185,14 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
|
||||
ReflectionTestUtils.setField(sample, "createdAt", null);
|
||||
ReflectionTestUtils.setField(sample, "email", null);
|
||||
|
||||
Scroll<Person> result = repository.findBy(
|
||||
Window<Person> result = repository.findBy(
|
||||
Example.of(sample, ExampleMatcher.matching().withMatcher("lastname", GenericPropertyMatcher::startsWith)),
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(KeysetScrollPosition.initial()));
|
||||
|
||||
assertThat(result).containsOnly(dave, leroi);
|
||||
assertThat(result.hasNext()).isTrue();
|
||||
|
||||
ScrollPosition position = result.lastPosition();
|
||||
ScrollPosition position = result.positionAt(result.size() - 1);
|
||||
result = repository.findBy(
|
||||
Example.of(sample, ExampleMatcher.matching().withMatcher("lastname", GenericPropertyMatcher::startsWith)),
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(position));
|
||||
|
||||
@@ -23,11 +23,11 @@ import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Box;
|
||||
@@ -123,8 +123,8 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
* @param scrollPosition
|
||||
* @return
|
||||
*/
|
||||
Scroll<Person> findTop2ByLastnameLikeOrderByLastnameAscFirstnameAsc(String lastname,
|
||||
KeysetScrollPosition scrollPosition);
|
||||
Window<Person> findTop2ByLastnameLikeOrderByLastnameAscFirstnameAsc(String lastname,
|
||||
ScrollPosition scrollPosition);
|
||||
|
||||
/**
|
||||
* Returns a scroll of {@link Person}s applying projections with a lastname matching the given one (*-wildcards
|
||||
@@ -134,7 +134,7 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
|
||||
* @param pageable
|
||||
* @return
|
||||
*/
|
||||
Scroll<PersonSummaryDto> findCursorProjectionByLastnameLike(String lastname, Pageable pageable);
|
||||
Window<PersonSummaryDto> findCursorProjectionByLastnameLike(String lastname, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Returns a page of {@link Person}s with a lastname matching the given one (*-wildcards supported).
|
||||
|
||||
@@ -50,10 +50,10 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
||||
import org.springframework.data.domain.KeysetScrollPosition;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Scroll;
|
||||
import org.springframework.data.domain.ScrollPosition;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.domain.Window;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
@@ -293,15 +293,15 @@ class ReactiveMongoRepositoryTests implements DirtiesStateExtension.StateFunctio
|
||||
@Test // GH-4308
|
||||
void appliesScrollingCorrectly() {
|
||||
|
||||
Scroll<Person> scroll = repository
|
||||
Window<Person> scroll = repository
|
||||
.findTop2ByLastnameLikeOrderByFirstnameAscLastnameAsc("*", KeysetScrollPosition.initial()).block();
|
||||
|
||||
assertThat(scroll).hasSize(2);
|
||||
assertThat(scroll).containsSequence(alicia, boyd);
|
||||
assertThat(scroll.isLast()).isFalse();
|
||||
|
||||
Scroll<Person> nextScroll = repository
|
||||
.findTop2ByLastnameLikeOrderByFirstnameAscLastnameAsc("*", scroll.lastPosition()).block();
|
||||
Window<Person> nextScroll = repository
|
||||
.findTop2ByLastnameLikeOrderByFirstnameAscLastnameAsc("*", scroll.positionAt(scroll.size() - 1)).block();
|
||||
|
||||
assertThat(nextScroll).hasSize(2);
|
||||
assertThat(nextScroll).containsSequence(carter, dave);
|
||||
@@ -474,7 +474,7 @@ class ReactiveMongoRepositoryTests implements DirtiesStateExtension.StateFunctio
|
||||
@Test // GH-4308
|
||||
void shouldScrollWithId() {
|
||||
|
||||
List<Scroll<Person>> capture = new ArrayList<>();
|
||||
List<Window<Person>> capture = new ArrayList<>();
|
||||
repository.findBy(person.id.in(Arrays.asList(dave.id, carter.id, boyd.id)), //
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(KeysetScrollPosition.initial())) //
|
||||
.as(StepVerifier::create) //
|
||||
@@ -482,10 +482,10 @@ class ReactiveMongoRepositoryTests implements DirtiesStateExtension.StateFunctio
|
||||
assertThat(actual).hasSize(2).containsExactly(boyd, carter);
|
||||
}).verifyComplete();
|
||||
|
||||
Scroll<Person> scroll = capture.get(0);
|
||||
Window<Person> scroll = capture.get(0);
|
||||
|
||||
repository.findBy(person.id.in(Arrays.asList(dave.id, carter.id, boyd.id)), //
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(scroll.lastPosition())) //
|
||||
q -> q.limit(2).sortBy(Sort.by("firstname")).scroll(scroll.positionAt(scroll.size() - 1))) //
|
||||
.as(StepVerifier::create) //
|
||||
.recordWith(() -> capture).assertNext(actual -> {
|
||||
assertThat(actual).containsOnly(dave);
|
||||
@@ -768,10 +768,10 @@ class ReactiveMongoRepositoryTests implements DirtiesStateExtension.StateFunctio
|
||||
@Query("{ lastname: { $in: ?0 }, age: { $gt : ?1 } }")
|
||||
Flux<Person> findStringQuery(Flux<String> lastname, Mono<Integer> age);
|
||||
|
||||
Mono<Scroll<Person>> findTop2ByLastnameLikeOrderByFirstnameAscLastnameAsc(String lastname,
|
||||
Mono<Window<Person>> findTop2ByLastnameLikeOrderByFirstnameAscLastnameAsc(String lastname,
|
||||
ScrollPosition scrollPosition);
|
||||
|
||||
Mono<Scroll<PersonSummaryDto>> findCursorProjectionByLastnameLike(String lastname, Pageable pageable);
|
||||
Mono<Window<PersonSummaryDto>> findCursorProjectionByLastnameLike(String lastname, Pageable pageable);
|
||||
|
||||
Flux<Person> findByLocationWithin(Circle circle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user