Align OffsetScrolling to zero-based indexes.

Closes: #3409
Original pull request: #3415
This commit is contained in:
Christoph Strobl
2024-04-03 14:50:05 +02:00
committed by Mark Paluch
parent 2e8c7c16cd
commit 0206de81b6
7 changed files with 27 additions and 10 deletions

View File

@@ -259,8 +259,8 @@ public class PartTreeJpaQuery extends AbstractJpaQuery {
@SuppressWarnings("ConstantConditions")
private Query restrictMaxResultsIfNecessary(Query query, @Nullable ScrollPosition scrollPosition) {
if (scrollPosition instanceof OffsetScrollPosition offset) {
query.setFirstResult(Math.toIntExact(offset.getOffset()));
if (scrollPosition instanceof OffsetScrollPosition offset && !offset.isInitial()) {
query.setFirstResult(Math.toIntExact(offset.getOffset()) + 1);
}
if (tree.isLimiting()) {

View File

@@ -71,7 +71,7 @@ public class ScrollDelegate<T> {
}
if (scrollPosition instanceof OffsetScrollPosition offset) {
return createWindow(result, limit, OffsetScrollPosition.positionFunction(offset.getOffset()));
return createWindow(result, limit, OffsetScrollPosition.positionFunction(offset.isInitial() ? 0 : offset.getOffset()));
}
throw new UnsupportedOperationException("ScrollPosition " + scrollPosition + " not supported");

View File

@@ -196,7 +196,9 @@ public class QuerydslJpaPredicateExecutor<T> implements QuerydslPredicateExecuto
select = (AbstractJPAQuery<?, ?>) querydsl.applySorting(sort, select);
if (scrollPosition instanceof OffsetScrollPosition offset) {
select.offset(offset.getOffset());
if(!offset.isInitial()) {
select.offset(offset.getOffset() + 1);
}
}
return select.createQuery();

View File

@@ -512,7 +512,9 @@ public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T
TypedQuery<T> query = getQuery(specToUse, domainClass, sort);
if (scrollPosition instanceof OffsetScrollPosition offset) {
query.setFirstResult(Math.toIntExact(offset.getOffset()));
if(!offset.isInitial()) {
query.setFirstResult(Math.toIntExact(offset.getOffset()) + 1);
}
}
return query;

View File

@@ -226,16 +226,16 @@ class UserRepositoryFinderTests {
assertThat(slice.hasNext()).isFalse();
}
@Test // DATAJPA-94
@Test // GH-3077, GH-3409
void executesQueryWithLimitAndScrollPosition() {
Window<User> first = userRepository.findByLastnameOrderByFirstname(Limit.of(1), //
ScrollPosition.offset(), //
ScrollPosition.offset(), // initial position no offset
"Matthews" //
);
Window<User> next = userRepository.findByLastnameOrderByFirstname(Limit.of(1), //
ScrollPosition.offset(1), //
ScrollPosition.offset(0), // first position, offset = 1
"Matthews" //
);
@@ -243,6 +243,17 @@ class UserRepositoryFinderTests {
assertThat(next).containsExactly(oliver);
}
@Test // GH-3409
void executesWindowQueryWithPageable() {
Window<User> first = userRepository.findByLastnameOrderByFirstname("Matthews", PageRequest.of(0,1));
Window<User> next = userRepository.findByLastnameOrderByFirstname("Matthews", PageRequest.of(1,1));
assertThat(first).containsExactly(dave);
assertThat(next).containsExactly(oliver);
}
@Test // GH-3077
void shouldProjectWithKeysetScrolling() {

View File

@@ -1430,7 +1430,7 @@ class UserRepositoryTests {
assertThat(previousWindow.hasNext()).isFalse();
}
@Test // GH-3015
@Test // GH-3015, GH-3407
void shouldApplyOffsetScrollPosition() {
User jane1 = new User("Jane", "Doe", "jane@doe1.com");
@@ -1441,7 +1441,7 @@ class UserRepositoryTests {
repository.saveAllAndFlush(Arrays.asList(john1, john2, jane1, jane2));
Window<User> atOffset3 = repository.findByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc("J",
ScrollPosition.offset(3));
ScrollPosition.offset(2));
assertThat(atOffset3).containsExactly(john2);
}

View File

@@ -197,6 +197,8 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
Window<User> findByLastnameOrderByFirstname(Limit limit, ScrollPosition scrollPosition, String lastname);
Window<User> findByLastnameOrderByFirstname(String lastname, Pageable page);
Window<NameOnly> findTop1ByLastnameOrderByFirstname(ScrollPosition scrollPosition, String lastname);
List<User> findByLastnameIgnoringCaseLike(String lastname);