Retain scroll direction in Keyset position function of the correct item.

Closes #2999
This commit is contained in:
Mark Paluch
2023-06-13 09:25:51 +02:00
parent c06cc38397
commit 3132f4945b
2 changed files with 29 additions and 3 deletions

View File

@@ -80,14 +80,14 @@ public class ScrollDelegate<T> {
JpaEntityInformation<T, ?> entity, List<T> result) {
KeysetScrollDelegate delegate = KeysetScrollDelegate.of(direction);
List<T> resultsToUse = delegate.postProcessResults(result);
List<T> resultsToUse = delegate.getResultWindow(delegate.postProcessResults(result), limit);
IntFunction<ScrollPosition> positionFunction = value -> {
T object = result.get(value);
T object = resultsToUse.get(value);
Map<String, Object> keys = entity.getKeyset(sort.stream().map(Order::getProperty).toList(), object);
return ScrollPosition.forward(keys);
return ScrollPosition.of(keys, direction);
};
return Window.from(delegate.getResultWindow(resultsToUse, limit), positionFunction, hasMoreElements(result, limit));

View File

@@ -60,6 +60,7 @@ import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher;
import org.springframework.data.domain.ExampleMatcher.StringMatcher;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.domain.ExampleMatcher.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.sample.Address;
import org.springframework.data.jpa.domain.sample.QUser;
@@ -1308,6 +1309,31 @@ class UserRepositoryTests {
assertThat(previousWindow.hasNext()).isTrue();
}
@Test // GH-2999
void scrollInitiallyByExampleKeysetBackward() {
User jane1 = new User("Jane", "Doe", "jane@doe1.com");
User jane2 = new User("Jane", "Doe", "jane@doe2.com");
User john1 = new User("John", "Doe", "john@doe1.com");
User john2 = new User("John", "Doe", "john@doe2.com");
repository.saveAllAndFlush(Arrays.asList(john1, john2, jane1, jane2));
Example<User> example = Example.of(new User("J", null, null),
matching().withMatcher("firstname", GenericPropertyMatcher::startsWith).withIgnorePaths("age", "createdAt",
"dateOfBirth"));
Window<User> firstWindow = repository.findBy(example,
q -> q.limit(2).sortBy(Sort.by("firstname", "emailAddress")).scroll(ScrollPosition.keyset().backward()));
assertThat(firstWindow).containsExactly(john1, john2);
Window<User> previousWindow = repository.findBy(example,
q -> q.limit(2).sortBy(Sort.by("firstname", "emailAddress")).scroll(firstWindow.positionAt(0)));
assertThat(previousWindow).containsExactly(jane1, jane2);
}
@Test // GH-2878
void scrollByPredicateOffset() {