Skip to content

Commit d14899f

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 8bade4e commit d14899f

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
@@ -39,6 +39,7 @@
3939
import org.mockito.junit.jupiter.MockitoSettings;
4040
import org.mockito.quality.Strictness;
4141

42+
import org.springframework.data.domain.Limit;
4243
import org.springframework.data.domain.Pageable;
4344
import org.springframework.data.domain.Sort;
4445
import org.springframework.data.jpa.repository.Temporal;
@@ -53,6 +54,7 @@
5354
* @author Thomas Darimont
5455
* @author Jens Schauder
5556
* @author Mark Paluch
57+
* @author Yanming Zhou
5658
*/
5759
@ExtendWith(MockitoExtension.class)
5860
@MockitoSettings(strictness = Strictness.LENIENT)
@@ -86,6 +88,8 @@ interface SampleRepository extends Repository<User, Long> {
8688

8789
User validWithPageable(@Param("username") String username, Pageable pageable);
8890

91+
User validWithLimit(@Param("username") String username, Limit limit);
92+
8993
User validWithSort(@Param("username") String username, Sort sort);
9094

9195
User validWithDefaultTemporalTypeParameter(@Temporal Date registerDate);
@@ -122,6 +126,40 @@ void bindWorksWithNullForPageable() throws Exception {
122126
verify(query).setParameter(eq(1), eq("foo"));
123127
}
124128

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

@@ -236,6 +274,11 @@ private void bind(Method method, JpaParameters parameters, Object[] values) {
236274
getAccessor(method, values), QueryParameterSetter.ErrorHandling.STRICT);
237275
}
238276

277+
private void bindAndPrepare(Method method, Object[] values) {
278+
ParameterBinderFactory.createBinder(createParameters(method)).bindAndPrepare(query,
279+
new QueryParameterSetter.QueryMetadata(query), getAccessor(method, values));
280+
}
281+
239282
private JpaParametersParameterAccessor getAccessor(Method method, Object... values) {
240283
return new JpaParametersParameterAccessor(createParameters(method), values);
241284
}

0 commit comments

Comments
 (0)