Extend query method special parameter types to any subclasses.
Spring Data Commons has a hard-coded list of special types than can be included in query methods including Pageable and Sort. A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input. This extends the list using an assignability check. Related: spring-projects/spring-data-jpa#2013 See #2626.
This commit is contained in:
committed by
Oliver Drotbohm
parent
042c1a0149
commit
1c42faf813
@@ -42,6 +42,7 @@ import org.springframework.util.Assert;
|
|||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
* @author Jens Schauder
|
* @author Jens Schauder
|
||||||
|
* @author Greg Turnquist
|
||||||
*/
|
*/
|
||||||
public class Parameter {
|
public class Parameter {
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ public class Parameter {
|
|||||||
this.parameter = parameter;
|
this.parameter = parameter;
|
||||||
this.parameterType = potentiallyUnwrapParameterType(parameter);
|
this.parameterType = potentiallyUnwrapParameterType(parameter);
|
||||||
this.isDynamicProjectionParameter = isDynamicProjectionParameter(parameter);
|
this.isDynamicProjectionParameter = isDynamicProjectionParameter(parameter);
|
||||||
this.name = TYPES.contains(parameter.getParameterType()) ? Lazy.of(Optional.empty()) : Lazy.of(() -> {
|
this.name = isSpecialParameterType(parameter.getParameterType()) ? Lazy.of(Optional.empty()) : Lazy.of(() -> {
|
||||||
Param annotation = parameter.getParameterAnnotation(Param.class);
|
Param annotation = parameter.getParameterAnnotation(Param.class);
|
||||||
return Optional.ofNullable(annotation == null ? parameter.getParameterName() : annotation.value());
|
return Optional.ofNullable(annotation == null ? parameter.getParameterName() : annotation.value());
|
||||||
});
|
});
|
||||||
@@ -92,7 +93,7 @@ public class Parameter {
|
|||||||
* @see #TYPES
|
* @see #TYPES
|
||||||
*/
|
*/
|
||||||
public boolean isSpecialParameter() {
|
public boolean isSpecialParameter() {
|
||||||
return isDynamicProjectionParameter || TYPES.contains(parameter.getParameterType());
|
return isDynamicProjectionParameter || isSpecialParameterType(parameter.getParameterType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -273,4 +274,22 @@ public class Parameter {
|
|||||||
|
|
||||||
return originalType;
|
return originalType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify is a given {@link Class} is either part of {@code TYPES} or an instanceof of one of its members. For
|
||||||
|
* example, {@code PageRequest} is an instance of {@code Pageable} (a member of {@code TYPES}).
|
||||||
|
*
|
||||||
|
* @param parameterType must not be {@literal null}.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static boolean isSpecialParameterType(Class<?> parameterType) {
|
||||||
|
|
||||||
|
for (Class<?> specialParameterType : TYPES) {
|
||||||
|
if (specialParameterType.isAssignableFrom(parameterType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.springframework.data.domain.Pageable;
|
|||||||
* Unit tests for {@link ParametersParameterAccessor}.
|
* Unit tests for {@link ParametersParameterAccessor}.
|
||||||
*
|
*
|
||||||
* @author Oliver Gierke
|
* @author Oliver Gierke
|
||||||
|
* @author Greg Turnquist
|
||||||
*/
|
*/
|
||||||
class ParametersParameterAccessorUnitTests {
|
class ParametersParameterAccessorUnitTests {
|
||||||
|
|
||||||
@@ -75,6 +76,19 @@ class ParametersParameterAccessorUnitTests {
|
|||||||
new Object[] { PageRequest.of(0, 10), "Foo" });
|
new Object[] { PageRequest.of(0, 10), "Foo" });
|
||||||
|
|
||||||
assertThat(accessor).hasSize(1);
|
assertThat(accessor).hasSize(1);
|
||||||
|
assertThat(accessor.getBindableValue(0)).isEqualTo("Foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // #2626
|
||||||
|
void handlesPageRequestAsAParameterType() throws NoSuchMethodException {
|
||||||
|
|
||||||
|
Method method = Sample.class.getMethod("methodWithPageRequest", PageRequest.class, String.class);
|
||||||
|
DefaultParameters parameters = new DefaultParameters(method);
|
||||||
|
|
||||||
|
ParameterAccessor accessor = new ParametersParameterAccessor(parameters, new Object[] { PageRequest.of(0, 10), "Foo" });
|
||||||
|
|
||||||
|
assertThat(accessor).hasSize(1);
|
||||||
|
assertThat(accessor.getBindableValue(0)).isEqualTo("Foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Sample {
|
interface Sample {
|
||||||
@@ -82,5 +96,7 @@ class ParametersParameterAccessorUnitTests {
|
|||||||
void method(String string, int integer);
|
void method(String string, int integer);
|
||||||
|
|
||||||
void method(Pageable pageable, String string);
|
void method(Pageable pageable, String string);
|
||||||
|
|
||||||
|
void methodWithPageRequest(PageRequest pageRequest, String string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user