Browse Source

ScrollUtils must not modify source query when creating scroll filter.

This commit makes sure to create a new filter query object if needed instead of modifying the source query.
In doing so we retain the original source and prevent errors when attempting to alter immutable sources.

Closes #5159
Original pull request: #5160
issue/5092
Christoph Strobl 1 month ago committed by Mark Paluch
parent
commit
bc997aae1d
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 11
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java
  2. 13
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java
  3. 9
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

11
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ScrollUtils.java

@ -29,6 +29,7 @@ import org.springframework.data.domain.ScrollPosition.Direction; @@ -29,6 +29,7 @@ import org.springframework.data.domain.ScrollPosition.Direction;
import org.springframework.data.domain.Window;
import org.springframework.data.mongodb.core.EntityOperations.Entity;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.lang.CheckReturnValue;
import org.springframework.util.Assert;
/**
@ -49,7 +50,6 @@ class ScrollUtils { @@ -49,7 +50,6 @@ class ScrollUtils {
*/
static KeysetScrollQuery createKeysetPaginationQuery(Query query, String idPropertyName) {
KeysetScrollPosition keyset = query.getKeyset();
Assert.notNull(keyset, "Query.keyset must not be null");
@ -145,6 +145,7 @@ class ScrollUtils { @@ -145,6 +145,7 @@ class ScrollUtils {
return fieldsObject;
}
@CheckReturnValue
public Document createQuery(KeysetScrollPosition keyset, Document queryObject, Document sortObject) {
Map<String, Object> keysetValues = keyset.getKeys();
@ -189,11 +190,13 @@ class ScrollUtils { @@ -189,11 +190,13 @@ class ScrollUtils {
}
}
if (!or.isEmpty()) {
queryObject.put("$or", or);
if (or.isEmpty()) {
return queryObject;
}
return queryObject;
Document filterQuery = new Document(queryObject);
filterQuery.put("$or", or);
return filterQuery;
}
protected String getComparator(int sortOrder) {

13
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

@ -232,6 +232,19 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie @@ -232,6 +232,19 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
assertThat(page).contains(carter);
}
@Test // GH-5159
void allowsToScrollThroughEntriesWithoutAnyCriteria() {
Window<Person> page = repository.findAllBy(Limit.of(2), ScrollPosition.keyset());
assertThat(page.isLast()).isFalse();
while (!page.isLast()) {
assertThat(page.size()).isEqualTo(2);
page = repository.findAllBy(Limit.of(2), page.positionAt(1));
}
}
@Test // GH-4397
void appliesLimitToScrollingCorrectly() {

9
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/PersonRepository.java

@ -126,6 +126,15 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query @@ -126,6 +126,15 @@ public interface PersonRepository extends MongoRepository<Person, String>, Query
@Query("{'age' : { '$lt' : ?0 } }")
List<Person> findByAgeLessThan(int age, Sort sort);
/**
* Returns a scroll of all {@link Person}s in natural order.
*
* @param limit window size
* @param scrollPosition scroll position start from
* @return
*/
Window<Person> findAllBy(Limit limit, ScrollPosition scrollPosition);
/**
* Returns a scroll of {@link Person}s with a lastname matching the given one (*-wildcards supported).
*

Loading…
Cancel
Save