diff --git a/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java b/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java index e79af5b61..72011696f 100644 --- a/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java +++ b/src/main/java/org/springframework/data/repository/core/support/AbstractRepositoryMetadata.java @@ -109,11 +109,7 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata { TypeInformation returnType = getReturnType(method); - if (ReactiveWrapperConverters.supports(returnType.getType())) { - return ReactiveWrapperConverters.unwrapWrapperTypes(returnType).getType(); - } - - return ReactiveWrapperConverters.unwrapWrapperTypes(QueryExecutionConverters.unwrapWrapperTypes(returnType)) + return QueryExecutionConverters.unwrapWrapperTypes(ReactiveWrapperConverters.unwrapWrapperTypes(returnType)) .getType(); } diff --git a/src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java b/src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java index 1424c7a2d..b1a14f9c8 100644 --- a/src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java +++ b/src/main/java/org/springframework/data/repository/core/support/QueryExecutionResultHandler.java @@ -126,7 +126,8 @@ class QueryExecutionResultHandler { result = unwrapOptional(result); - if (QueryExecutionConverters.supports(expectedReturnType)) { + if (QueryExecutionConverters.supports(expectedReturnType) + || ReactiveWrapperConverters.supports(expectedReturnType)) { // For a wrapper type, try nested resolution first result = postProcessInvocationResult(result, nestingLevel + 1, descriptor); diff --git a/src/main/java/org/springframework/data/repository/query/Parameter.java b/src/main/java/org/springframework/data/repository/query/Parameter.java index faca4ba02..46035e77c 100644 --- a/src/main/java/org/springframework/data/repository/query/Parameter.java +++ b/src/main/java/org/springframework/data/repository/query/Parameter.java @@ -230,7 +230,7 @@ public class Parameter { TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); return bound - .equals(ReactiveWrapperConverters.unwrapWrapperTypes(QueryExecutionConverters.unwrapWrapperTypes(returnType))); + .equals(QueryExecutionConverters.unwrapWrapperTypes(ReactiveWrapperConverters.unwrapWrapperTypes(returnType))); } /** diff --git a/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java b/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java index 3582d01a9..fcf6aae3b 100644 --- a/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java @@ -21,6 +21,7 @@ import java.util.Optional; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.repository.util.QueryExecutionConverters; +import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -64,7 +65,8 @@ public class ParametersParameterAccessor implements ParameterAccessor { private static boolean requiresUnwrapping(Object[] values) { for (Object value : values) { - if (value != null && QueryExecutionConverters.supports(value.getClass())) { + if (value != null && (QueryExecutionConverters.supports(value.getClass()) + || ReactiveWrapperConverters.supports(value.getClass()))) { return true; } } diff --git a/src/main/java/org/springframework/data/repository/query/QueryMethod.java b/src/main/java/org/springframework/data/repository/query/QueryMethod.java index 7d851913a..ed4394726 100644 --- a/src/main/java/org/springframework/data/repository/query/QueryMethod.java +++ b/src/main/java/org/springframework/data/repository/query/QueryMethod.java @@ -29,6 +29,7 @@ import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.EntityMetadata; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.util.QueryExecutionConverters; +import org.springframework.data.repository.util.ReactiveWrapperConverters; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.Lazy; import org.springframework.data.util.TypeInformation; @@ -271,7 +272,8 @@ public class QueryMethod { private static Class potentiallyUnwrapReturnTypeFor(RepositoryMetadata metadata, Method method) { TypeInformation returnType = metadata.getReturnType(method); - if (QueryExecutionConverters.supports(returnType.getType())) { + if (QueryExecutionConverters.supports(returnType.getType()) + || ReactiveWrapperConverters.supports(returnType.getType())) { // unwrap only one level to handle cases like Future> correctly. diff --git a/src/main/java/org/springframework/data/repository/util/ClassUtils.java b/src/main/java/org/springframework/data/repository/util/ClassUtils.java index f10bd1f0a..4ef5045bf 100644 --- a/src/main/java/org/springframework/data/repository/util/ClassUtils.java +++ b/src/main/java/org/springframework/data/repository/util/ClassUtils.java @@ -187,6 +187,8 @@ public abstract class ClassUtils { private static TypeInformation getEffectivelyReturnedTypeFrom(Method method) { TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); - return QueryExecutionConverters.supports(returnType.getType()) ? returnType.getRequiredComponentType() : returnType; + return QueryExecutionConverters.supports(returnType.getType()) + || ReactiveWrapperConverters.supports(returnType.getType()) ? returnType.getRequiredComponentType() + : returnType; } } diff --git a/src/test/java/org/springframework/data/repository/query/QueryMethodUnitTests.java b/src/test/java/org/springframework/data/repository/query/QueryMethodUnitTests.java index 94d1d78b2..62779269c 100755 --- a/src/test/java/org/springframework/data/repository/query/QueryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/repository/query/QueryMethodUnitTests.java @@ -28,6 +28,7 @@ import java.util.concurrent.Future; import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -45,6 +46,7 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat * @author Oliver Gierke * @author Thomas Darimont * @author Maciek Opała + * @author Mark Paluch */ class QueryMethodUnitTests { @@ -208,7 +210,7 @@ class QueryMethodUnitTests { * @see DATACMNS-940 */ @Test - void detectsSinglValueWrapperWithinWrapper() throws Exception { + void detectsSingleValueWrapperWithinWrapper() throws Exception { RepositoryMetadata repositoryMetadata = new DefaultRepositoryMetadata(SampleRepository.class); Method method = SampleRepository.class.getMethod("returnsFutureOfOption"); @@ -234,6 +236,19 @@ class QueryMethodUnitTests { assertThat(new QueryMethod(method, metadata, factory).isCollectionQuery()).isFalse(); } + @Test // DATACMNS-1762 + void detectsReactiveSliceQuery() throws Exception { + + RepositoryMetadata repositoryMetadata = new DefaultRepositoryMetadata(SampleRepository.class); + Method method = SampleRepository.class.getMethod("reactiveSlice"); + + QueryMethod queryMethod = new QueryMethod(method, repositoryMetadata, factory); + ReturnedType returnedType = queryMethod.getResultProcessor().getReturnedType(); + assertThat(queryMethod.isSliceQuery()).isTrue(); + assertThat(returnedType.getTypeToRead()).isEqualTo(User.class); + assertThat(returnedType.getDomainType()).isEqualTo(User.class); + } + interface SampleRepository extends Repository { String pagingMethodWithInvalidReturnType(Pageable pageable); @@ -278,6 +293,8 @@ class QueryMethodUnitTests { Future> returnsFutureOfSeq(); Future> returnsFutureOfOption(); + + Mono> reactiveSlice(); } class User {