DATACMNS-1802 - Add support for suspend repository query methods returning List<T>.

We now support returning List<T> from a suspended repository query method to simplify consumption of collection queries.
This commit is contained in:
Mark Paluch
2020-09-22 14:34:47 +02:00
parent af00979784
commit 82cb36f727
4 changed files with 38 additions and 9 deletions

View File

@@ -23,9 +23,11 @@ import reactor.core.publisher.Mono;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.stream.Stream;
import org.reactivestreams.Publisher;
import org.springframework.core.KotlinDetector;
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocation;
import org.springframework.data.repository.core.support.RepositoryMethodInvocationListener.RepositoryMethodInvocationResult;
@@ -176,6 +178,10 @@ abstract class RepositoryMethodInvoker {
return ReactiveWrapperConverters.toWrapper(result, returnedType);
}
if (Collection.class.isAssignableFrom(returnedType)) {
result = Flux.from(result).collectList();
}
return AwaitKt.awaitFirstOrNull(result, continuation);
} catch (Exception e) {
multicaster.notifyListeners(method, args, computeInvocationResult(invocationResultCaptor.error(e)));
@@ -188,8 +194,6 @@ abstract class RepositoryMethodInvoker {
captured.getDuration());
}
interface Invokable {
@Nullable

View File

@@ -77,7 +77,7 @@ public class QueryMethod {
});
this.method = method;
this.unwrappedReturnType = potentiallyUnwrapReturnTypeFor(method);
this.unwrappedReturnType = potentiallyUnwrapReturnTypeFor(metadata, method);
this.parameters = createParameters(method);
this.metadata = metadata;
@@ -255,7 +255,7 @@ public class QueryMethod {
return false;
}
Class<?> returnType = method.getReturnType();
Class<?> returnType = metadata.getReturnType(method).getType();
if (QueryExecutionConverters.supports(returnType) && !QueryExecutionConverters.isSingleValue(returnType)) {
return true;
@@ -268,13 +268,14 @@ public class QueryMethod {
return ClassTypeInformation.from(unwrappedReturnType).isCollectionLike();
}
private static Class<? extends Object> potentiallyUnwrapReturnTypeFor(Method method) {
private static Class<? extends Object> potentiallyUnwrapReturnTypeFor(RepositoryMetadata metadata, Method method) {
if (QueryExecutionConverters.supports(method.getReturnType())) {
TypeInformation<?> returnType = metadata.getReturnType(method);
if (QueryExecutionConverters.supports(returnType.getType())) {
// unwrap only one level to handle cases like Future<List<Entity>> correctly.
TypeInformation<?> componentType = ClassTypeInformation.fromReturnTypeOf(method).getComponentType();
TypeInformation<?> componentType = returnType.getComponentType();
if (componentType == null) {
throw new IllegalStateException(
@@ -284,7 +285,7 @@ public class QueryMethod {
return componentType.getType();
}
return method.getReturnType();
return returnType.getType();
}
private static void assertReturnTypeAssignable(Method method, Set<Class<?>> types) {