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:
Greg L. Turnquist
2022-05-11 16:38:53 -05:00
committed by Oliver Drotbohm
parent 503d158a32
commit e7c3541d39
2 changed files with 38 additions and 5 deletions

View File

@@ -42,6 +42,7 @@ import org.springframework.util.Assert;
* @author Oliver Gierke
* @author Mark Paluch
* @author Jens Schauder
* @author Greg Turnquist
*/
public class Parameter {
@@ -79,7 +80,7 @@ public class Parameter {
this.parameter = parameter;
this.parameterType = potentiallyUnwrapParameterType(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);
return Optional.ofNullable(annotation == null ? parameter.getParameterName() : annotation.value());
});
@@ -92,7 +93,7 @@ public class Parameter {
* @see #TYPES
*/
public boolean isSpecialParameter() {
return isDynamicProjectionParameter || TYPES.contains(parameter.getParameterType());
return isDynamicProjectionParameter || isSpecialParameterType(parameter.getParameterType());
}
/**
@@ -269,4 +270,22 @@ public class Parameter {
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;
}
}