Skip to content

Commit 912f38a

Browse files
quaffmp911de
authored andcommitted
Ignore offset for if it defaults to 0.
Avoid calling `Query.setFirstResult(0)` which maybe generated sql contains unwanted `offset 0` when using query methods accepting `Limit` . Closes #3242 Original pull request: #3454
1 parent 0a722e9 commit 912f38a

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
* @author Mark Paluch
3131
* @author Christoph Strobl
3232
* @author Jens Schauder
33+
* @author Yanming Zhou
3334
*/
3435
public class ParameterBinder {
3536

@@ -101,7 +102,11 @@ Query bindAndPrepare(Query query, QueryParameterSetter.QueryMetadata metadata,
101102
return query;
102103
}
103104

104-
query.setFirstResult(PageableUtils.getOffsetAsInteger(accessor.getPageable()));
105+
// see #3242
106+
if (!parameters.hasLimitParameter()) {
107+
// offset is meaningless if Limit parameter present
108+
query.setFirstResult(PageableUtils.getOffsetAsInteger(accessor.getPageable()));
109+
}
105110
query.setMaxResults(accessor.getPageable().getPageSize());
106111

107112
return query;

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java

+43
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.mockito.junit.jupiter.MockitoSettings;
4242
import org.mockito.quality.Strictness;
4343

44+
import org.springframework.data.domain.Limit;
4445
import org.springframework.data.domain.Pageable;
4546
import org.springframework.data.domain.Sort;
4647
import org.springframework.data.jpa.repository.Temporal;
@@ -55,6 +56,7 @@
5556
* @author Thomas Darimont
5657
* @author Jens Schauder
5758
* @author Mark Paluch
59+
* @author Yanming Zhou
5860
*/
5961
@ExtendWith(MockitoExtension.class)
6062
@MockitoSettings(strictness = Strictness.LENIENT)
@@ -88,6 +90,8 @@ interface SampleRepository extends Repository<User, Long> {
8890

8991
User validWithPageable(@Param("username") String username, Pageable pageable);
9092

93+
User validWithLimit(@Param("username") String username, Limit limit);
94+
9195
User validWithSort(@Param("username") String username, Sort sort);
9296

9397
User validWithDefaultTemporalTypeParameter(@Temporal Date registerDate);
@@ -124,6 +128,40 @@ void bindWorksWithNullForPageable() throws Exception {
124128
verify(query).setParameter(eq(1), eq("foo"));
125129
}
126130

131+
@Test
132+
void bindAndPrepareWorksWithPageable() throws Exception {
133+
134+
Method validWithPageable = SampleRepository.class.getMethod("validWithPageable", String.class, Pageable.class);
135+
136+
Object[] values = { "foo", Pageable.ofSize(10).withPage(3) };
137+
bindAndPrepare(validWithPageable, values);
138+
verify(query).setParameter(eq(1), eq("foo"));
139+
verify(query).setFirstResult(eq(30));
140+
verify(query).setMaxResults(eq(10));
141+
}
142+
143+
@Test
144+
void bindWorksWithNullForLimit() throws Exception {
145+
146+
Method validWithLimit = SampleRepository.class.getMethod("validWithLimit", String.class, Limit.class);
147+
148+
Object[] values = { "foo", null };
149+
bind(validWithLimit, values);
150+
verify(query).setParameter(eq(1), eq("foo"));
151+
}
152+
153+
@Test
154+
void bindAndPrepareWorksWithLimit() throws Exception {
155+
156+
Method validWithLimit = SampleRepository.class.getMethod("validWithLimit", String.class, Limit.class);
157+
158+
Object[] values = { "foo", Limit.of(10) };
159+
bindAndPrepare(validWithLimit, values);
160+
verify(query).setParameter(eq(1), eq("foo"));
161+
verify(query).setMaxResults(eq(10));
162+
verify(query, never()).setFirstResult(anyInt());
163+
}
164+
127165
@Test
128166
void usesIndexedParametersIfNoParamAnnotationPresent() {
129167

@@ -238,6 +276,11 @@ private void bind(Method method, JpaParameters parameters, Object[] values) {
238276
getAccessor(method, values), QueryParameterSetter.ErrorHandling.STRICT);
239277
}
240278

279+
private void bindAndPrepare(Method method, Object[] values) {
280+
ParameterBinderFactory.createBinder(createParameters(method)).bindAndPrepare(query,
281+
new QueryParameterSetter.QueryMetadata(query), getAccessor(method, values));
282+
}
283+
241284
private JpaParametersParameterAccessor getAccessor(Method method, Object... values) {
242285
return new JpaParametersParameterAccessor(createParameters(method), values);
243286
}

0 commit comments

Comments
 (0)