From 5982f9812e44d65900405c7e9abae0f556b12ac9 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 26 Mar 2024 07:04:48 +0100 Subject: [PATCH 1/3] Prepare issue branch. --- pom.xml | 4 ++-- spring-data-envers/pom.xml | 4 ++-- spring-data-jpa-distribution/pom.xml | 2 +- spring-data-jpa/pom.xml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index dd336ca646..d05c9750ef 100755 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-jpa-parent - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT pom Spring Data JPA Parent @@ -41,7 +41,7 @@ 4.8 8.0.33 42.6.0 - 3.3.0-SNAPSHOT + 3.3.x-3070-SNAPSHOT 0.10.3 org.hibernate diff --git a/spring-data-envers/pom.xml b/spring-data-envers/pom.xml index 470678d048..197a2a37cc 100755 --- a/spring-data-envers/pom.xml +++ b/spring-data-envers/pom.xml @@ -5,12 +5,12 @@ org.springframework.data spring-data-envers - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT org.springframework.data spring-data-jpa-parent - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT ../pom.xml diff --git a/spring-data-jpa-distribution/pom.xml b/spring-data-jpa-distribution/pom.xml index 6bd074181c..bff325f01c 100644 --- a/spring-data-jpa-distribution/pom.xml +++ b/spring-data-jpa-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-jpa-parent - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT ../pom.xml diff --git a/spring-data-jpa/pom.xml b/spring-data-jpa/pom.xml index 67ad4cabb2..bb4a75b0a9 100644 --- a/spring-data-jpa/pom.xml +++ b/spring-data-jpa/pom.xml @@ -6,7 +6,7 @@ org.springframework.data spring-data-jpa - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT Spring Data JPA Spring Data module for JPA repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-jpa-parent - 3.3.0-SNAPSHOT + 3.3.x-3409-SNAPSHOT ../pom.xml From 964572b16c2293d79756d4af2c3d930421c7e76e Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 3 Apr 2024 14:50:05 +0200 Subject: [PATCH 2/3] Align scroll implementation to changes in data-commons. --- .../data/jpa/repository/query/PartTreeJpaQuery.java | 2 +- .../data/jpa/repository/query/ScrollDelegate.java | 2 +- .../jpa/repository/support/QuerydslJpaPredicateExecutor.java | 4 +++- .../data/jpa/repository/support/SimpleJpaRepository.java | 4 +++- 4 files changed, 8 insertions(+), 4 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 479dc4b52e..fd83407557 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 @@ -259,7 +259,7 @@ public Query createQuery(JpaParametersParameterAccessor accessor) { @SuppressWarnings("ConstantConditions") private Query restrictMaxResultsIfNecessary(Query query, @Nullable ScrollPosition scrollPosition) { - if (scrollPosition instanceof OffsetScrollPosition offset) { + if (scrollPosition instanceof OffsetScrollPosition offset && !offset.isInitial()) { query.setFirstResult(Math.toIntExact(offset.getOffset())); } diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ScrollDelegate.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ScrollDelegate.java index 90c055578d..d529b73f7d 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ScrollDelegate.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ScrollDelegate.java @@ -71,7 +71,7 @@ public Window scroll(Query query, Sort sort, ScrollPosition scrollPosition) { } 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"); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java index 946dfb23fb..606d56631e 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/QuerydslJpaPredicateExecutor.java @@ -196,7 +196,9 @@ public R findBy(Predicate predicate, Function) querydsl.applySorting(sort, select); if (scrollPosition instanceof OffsetScrollPosition offset) { - select.offset(offset.getOffset()); + if(!offset.isInitial()) { + select.offset(offset.getOffset() + 1); + } } return select.createQuery(); diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 31abc19187..879e683865 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -512,7 +512,9 @@ private R doFindBy(Specification spec, Class domainClass, TypedQuery 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; From 52e2283479b9cd1d3054f36fed9b3d178023fe3b Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 4 Apr 2024 10:40:07 +0200 Subject: [PATCH 3/3] Set first result as exclusive for PartTreeQuery --- .../jpa/repository/query/PartTreeJpaQuery.java | 2 +- .../repository/UserRepositoryFinderTests.java | 17 ++++++++++++++--- .../jpa/repository/UserRepositoryTests.java | 4 ++-- .../jpa/repository/sample/UserRepository.java | 2 ++ 4 files changed, 19 insertions(+), 6 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 fd83407557..3b799258dc 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 @@ -260,7 +260,7 @@ public Query createQuery(JpaParametersParameterAccessor accessor) { private Query restrictMaxResultsIfNecessary(Query query, @Nullable ScrollPosition scrollPosition) { if (scrollPosition instanceof OffsetScrollPosition offset && !offset.isInitial()) { - query.setFirstResult(Math.toIntExact(offset.getOffset())); + query.setFirstResult(Math.toIntExact(offset.getOffset()) + 1); } if (tree.isLimiting()) { diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java index bea13c14ad..6a8c06789d 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java @@ -226,16 +226,16 @@ void executesQueryToSliceWithUnpaged() { assertThat(slice.hasNext()).isFalse(); } - @Test // DATAJPA-94 + @Test // GH-3077, GH-3409 void executesQueryWithLimitAndScrollPosition() { Window first = userRepository.findByLastnameOrderByFirstname(Limit.of(1), // - ScrollPosition.offset(), // + ScrollPosition.offset(), // initial position no offset "Matthews" // ); Window next = userRepository.findByLastnameOrderByFirstname(Limit.of(1), // - ScrollPosition.offset(1), // + ScrollPosition.offset(0), // first position, offset = 1 "Matthews" // ); @@ -243,6 +243,17 @@ void executesQueryWithLimitAndScrollPosition() { assertThat(next).containsExactly(oliver); } + @Test // GH-3409 + void executesWindowQueryWithPageable() { + + Window first = userRepository.findByLastnameOrderByFirstname("Matthews", PageRequest.of(0,1)); + + Window next = userRepository.findByLastnameOrderByFirstname("Matthews", PageRequest.of(1,1)); + + assertThat(first).containsExactly(dave); + assertThat(next).containsExactly(oliver); + } + @Test // GH-3077 void shouldProjectWithKeysetScrolling() { 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 4b802f9773..6f70724709 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 @@ -1430,7 +1430,7 @@ void scrollByPartTreeKeysetBackward() { 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 @@ void shouldApplyOffsetScrollPosition() { repository.saveAllAndFlush(Arrays.asList(john1, john2, jane1, jane2)); Window atOffset3 = repository.findByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc("J", - ScrollPosition.offset(3)); + ScrollPosition.offset(2)); assertThat(atOffset3).containsExactly(john2); } 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 2e782982aa..0d898449a1 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 @@ -197,6 +197,8 @@ Window findTop3ByFirstnameStartingWithOrderByFirstnameAscEmailAddressAsc(S Window findByLastnameOrderByFirstname(Limit limit, ScrollPosition scrollPosition, String lastname); + Window findByLastnameOrderByFirstname(String lastname, Pageable page); + Window findTop1ByLastnameOrderByFirstname(ScrollPosition scrollPosition, String lastname); List findByLastnameIgnoringCaseLike(String lastname);