Query method parameters annotated with @Param are not considered projection parameters.

This is a 2.7.x adapted fix for #1452 (the actual fix for 3.x contained in #2770). We temporarily support the use of @Param on Class parameters to allow them to be be used as actual query parameters.

On 3.0.x the general parameter handling gets smarter so that this mitigation can be phased out pretty quickly, but this here seems to be a simple enough fix for those who cannot upgrade to 3.0 any time soon.

Closes #2770.
See #1452.
Original pull request: #2772
This commit is contained in:
Oliver Drotbohm
2023-02-01 17:31:28 +01:00
committed by Mark Paluch
parent 7189e0735a
commit 5dad677bf1
2 changed files with 23 additions and 7 deletions

View File

@@ -215,6 +215,10 @@ public class Parameter {
*/
private static boolean isDynamicProjectionParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(Param.class)) {
return false;
}
Method method = parameter.getMethod();
if (method == null) {
@@ -232,7 +236,8 @@ public class Parameter {
TypeInformation<Object> returnType = ClassTypeInformation.fromReturnTypeOf(method);
return bound
.equals(QueryExecutionConverters.unwrapWrapperTypes(ReactiveWrapperConverters.unwrapWrapperTypes(returnType)));
.equals(QueryExecutionConverters
.unwrapWrapperTypes(ReactiveWrapperConverters.unwrapWrapperTypes(returnType)));
}
/**

View File

@@ -17,6 +17,7 @@ package org.springframework.data.repository.query;
import static org.assertj.core.api.Assertions.*;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
@@ -48,14 +49,20 @@ class ParameterUnitTests {
assertThat(parameter.isDynamicProjectionParameter()).isTrue();
}
@Test // #1452
void doesNotConsiderAtParamAnnotatedClassParameterDynamicProjectionOne() throws Exception {
Parameter parameter = new Parameter(getMethodParameter("atParamOnClass"));
assertThat(parameter.isDynamicProjectionParameter()).isFalse();
}
@NotNull
private MethodParameter getMethodParameter(String methodName) throws NoSuchMethodException {
return new MethodParameter( //
this.getClass().getDeclaredMethod( //
methodName, //
Class.class //
), //
0);
Method method = getClass().getDeclaredMethod(methodName, Class.class);
return new MethodParameter(method, 0);
}
<T> List<T> dynamicProjectionWithList(Class<T> type) {
@@ -65,4 +72,8 @@ class ParameterUnitTests {
<T> Stream<T> dynamicProjectionWithStream(Class<T> type) {
return Stream.empty();
}
<T> T atParamOnClass(@Param("type") Class<T> type) {
return null;
}
}