DATACMNS-1689 - Resolve suspendable query method result type from Continuation parameter.

Kotlin coroutine methods are compiled returning Object so the original return type gets lost. We resolve the return type from the Continuation parameter that synthetized as last parameter in a coroutine method declaration.
This commit is contained in:
Mark Paluch
2020-03-19 10:45:27 +01:00
parent f047743cfa
commit a0abf009a0
2 changed files with 96 additions and 1 deletions

View File

@@ -18,8 +18,10 @@ package org.springframework.data.repository.core.support;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.springframework.core.KotlinDetector;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.CrudMethods;
@@ -27,6 +29,7 @@ import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.util.QueryExecutionConverters;
import org.springframework.data.repository.util.ReactiveWrappers;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.KotlinReflectionUtils;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
@@ -79,7 +82,20 @@ public abstract class AbstractRepositoryMetadata implements RepositoryMetadata {
* @see org.springframework.data.repository.core.RepositoryMetadata#getReturnedDomainClass(java.lang.reflect.Method)
*/
public Class<?> getReturnedDomainClass(Method method) {
return QueryExecutionConverters.unwrapWrapperTypes(typeInformation.getReturnType(method)).getType();
TypeInformation<?> returnType = null;
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinReflectionUtils.isSuspend(method)) {
// the last parameter is Continuation<? super T> or Continuation<? super Flow<? super T>>
List<TypeInformation<?>> types = typeInformation.getParameterTypes(method);
returnType = types.get(types.size() - 1).getComponentType();
}
if (returnType == null) {
returnType = typeInformation.getReturnType(method);
}
return QueryExecutionConverters.unwrapWrapperTypes(returnType).getType();
}
/*