> from(E entity, Predicate super P> filter, Predicate traversalGuard,
+ DefaultPersistentPropertyPath
basePath) {
+
Set> properties = new HashSet<>();
PropertyHandler propertyTester = persistentProperty -> {
@@ -254,7 +259,7 @@ private Collection> from(TypeInformation type,
}
if (traversalGuard.and(IS_ENTITY).test(persistentProperty)) {
- properties.addAll(from(typeInformation, filter, traversalGuard, currentPath));
+ properties.addAll(from(context.getPersistentEntity(persistentProperty), filter, traversalGuard, currentPath));
}
};
diff --git a/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java b/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java
index ae75bf3381..322948c4d9 100644
--- a/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java
+++ b/src/main/java/org/springframework/data/projection/ProjectingMethodInterceptor.java
@@ -27,7 +27,6 @@
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
-
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.util.ClassTypeInformation;
@@ -45,6 +44,7 @@
*
* @author Oliver Gierke
* @author Mark Paluch
+ * @author Christoph Strobl
* @since 1.10
*/
class ProjectingMethodInterceptor implements MethodInterceptor {
@@ -98,14 +98,22 @@ protected Object potentiallyConvertResult(TypeInformation> type, @Nullable Obj
return null;
}
- if (type.isCollectionLike() && !ClassUtils.isPrimitiveArray(type.getType())) {
+ Class> targetType = type.getType();
+
+ if (type.isCollectionLike() && !ClassUtils.isPrimitiveArray(targetType)) {
return projectCollectionElements(asCollection(result), type);
} else if (type.isMap()) {
return projectMapValues((Map, ?>) result, type);
- } else if (conversionRequiredAndPossible(result, type.getType())) {
- return conversionService.convert(result, type.getType());
+ } else if (ClassUtils.isAssignable(targetType, result.getClass())) {
+ return result;
+ } else if (conversionService.canConvert(result.getClass(), targetType)) {
+ return conversionService.convert(result, targetType);
+ } else if (targetType.isInterface()) {
+ return getProjection(result, targetType);
} else {
- return getProjection(result, type.getType());
+ throw new UnsupportedOperationException(
+ String.format("Cannot project %s to %s. Target type is not an interface and no matching Converter found!",
+ ClassUtils.getDescriptiveType(result), ClassUtils.getQualifiedName(targetType)));
}
}
@@ -155,28 +163,11 @@ private Map