Consider enclosing class for dynamic projection parameter detection.

We now consider the enclosing class to determine correct generic typing.

Closes #3020
This commit is contained in:
Mark Paluch
2024-01-11 11:04:46 +01:00
parent 6623bd8d91
commit 0093c9085b
4 changed files with 22 additions and 4 deletions

View File

@@ -260,7 +260,7 @@ public class Parameter {
throw new IllegalArgumentException("Parameter is not associated with any method");
}
var returnType = TypeInformation.fromReturnTypeOf(method);
var returnType = TypeInformation.fromReturnTypeOf(method, parameter.getContainingClass());
var unwrapped = QueryExecutionConverters.unwrapWrapperTypes(returnType);
var reactiveUnwrapped = ReactiveWrapperConverters.unwrapWrapperTypes(unwrapped);

View File

@@ -146,7 +146,7 @@ public abstract class QuerydslPredicateArgumentResolverSupport {
throw new IllegalArgumentException("Method parameter is not backed by a method");
}
return detectDomainType(TypeInformation.fromReturnTypeOf(method));
return detectDomainType(TypeInformation.fromReturnTypeOf(method, parameter.getContainingClass()));
}
private static TypeInformation<?> detectDomainType(TypeInformation<?> source) {

View File

@@ -23,10 +23,10 @@ import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.springframework.core.MethodParameter;
import org.springframework.data.repository.query.ParametersUnitTests.User;
import org.springframework.data.util.TypeInformation;
@@ -85,7 +85,6 @@ class ParameterUnitTests {
assertThat(parameter.isDynamicProjectionParameter()).isFalse();
}
@NotNull
private MethodParameter getMethodParameter(String methodName) throws NoSuchMethodException {
return new MethodParameter(this.getClass().getDeclaredMethod(methodName, Class.class), 0);
}
@@ -117,4 +116,5 @@ class ParameterUnitTests {
<T> T atParamOnClass(@Param("type") Class<T> type) {
return null;
}
}

View File

@@ -159,6 +159,16 @@ class ParametersUnitTests {
assertThat(parameters.getParameter(2).isDynamicProjectionParameter()).isFalse();
}
@Test // GH-3020
void detectsDynamicParametrizedProjectionParameter() throws Exception {
var method = ParametrizedRepository.class.getMethod("dynamicBind", Class.class);
var parameters = new DefaultParameters(
ParametersSource.of(new DefaultRepositoryMetadata(ParametrizedRepository.class), method));
assertThat(parameters.getParameter(0).isDynamicProjectionParameter()).isTrue();
}
@Test // DATACMNS-863
void unwrapsOptionals() throws Exception {
@@ -272,4 +282,12 @@ class ParametersUnitTests {
interface TypedInterface extends Intermediate<User, Long> {}
interface GenericRepository<T, ID> extends Repository<T, ID> {
<P extends Projection<T>> Optional<P> dynamicBind(Class<P> type);
}
interface ParametrizedRepository extends GenericRepository<User, Long> {}
interface Projection<T> {}
}