From fb4214ca366ef3f53b7acc1ced20422edbdd5dfb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 26 Jun 2023 10:33:58 +0200 Subject: [PATCH] Correctly apply OffsetScrollPosition to derived queries. We now apply the scroll position correctly regardless of whether the query is limited. Previously, we applied the position only if the query was limited. Closes #3015 --- .../jpa/repository/query/PartTreeJpaQuery.java | 8 ++++---- .../jpa/repository/UserRepositoryTests.java | 17 ++++++++++++++++- .../jpa/repository/sample/UserRepository.java | 5 +++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index 78cfde34a..b1ccc6943 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -255,11 +255,11 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { @SuppressWarnings("ConstantConditions") private Query restrictMaxResultsIfNecessary(Query query, @Nullable ScrollPosition scrollPosition) { - if (tree.isLimiting()) { + if (scrollPosition instanceof OffsetScrollPosition offset) { + query.setFirstResult(Math.toIntExact(offset.getOffset())); + } - if (scrollPosition instanceof OffsetScrollPosition offset) { - query.setFirstResult(Math.toIntExact(offset.getOffset())); - } + if (tree.isLimiting()) { if (query.getMaxResults() != Integer.MAX_VALUE) { /* diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index c9d22e52b..e8f2848dd 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -60,7 +60,6 @@ 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; @@ -1432,6 +1431,22 @@ class UserRepositoryTests { assertThat(previousWindow.hasNext()).isFalse(); } + @Test // GH-3015 + void shouldApplyOffsetScrollPosition() { + + 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)); + + Window atOffset3 = repository.findByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc("J", + ScrollPosition.offset(3)); + + assertThat(atOffset3).containsExactly(john2); + } + @Test // DATAJPA-491 void sortByNestedAssociationPropertyWithSortInPageable() { diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index a1bd08711..fad09d8a2 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -26,6 +26,7 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; +import org.springframework.data.domain.OffsetScrollPosition; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; @@ -155,6 +156,8 @@ public interface UserRepository extends JpaRepository, JpaSpecifi Window findTop3ByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc(String firstname, ScrollPosition position); + Window findByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc(String firstname, ScrollPosition position); + List findByFirstnameNotIn(Collection firstnames); // DATAJPA-292 @@ -722,6 +725,8 @@ public interface UserRepository extends JpaRepository, JpaSpecifi @Query("select u from User u where u.firstname >= (select Min(u0.firstname) from User u0)") List findProjectionBySubselect(); + Window findBy(OffsetScrollPosition position); + interface RolesAndFirstname { String getFirstname();