diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeDiscoverer.java b/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeDiscoverer.java index 8ecd493ee..e4d052c4e 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeDiscoverer.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeDiscoverer.java @@ -113,7 +113,9 @@ class TypeDiscoverer implements TypeInformation { } TypeInformation propertyInformation = getPropertyInformation(fieldname); - fieldTypes.put(fieldname, propertyInformation); + if (propertyInformation != null) { + fieldTypes.put(fieldname, propertyInformation); + } return propertyInformation; } @@ -144,6 +146,15 @@ class TypeDiscoverer implements TypeInformation { return resolveType(type); } + /* (non-Javadoc) + * @see org.springframework.data.util.TypeInformation#isMap() + */ + @Override + public boolean isMap() { + Class rawType = getType(); + return rawType == null ? false : Map.class.isAssignableFrom(rawType); + } + /* (non-Javadoc) * @see org.springframework.data.util.TypeInformation#getMapValueType() */ @@ -157,12 +168,22 @@ class TypeDiscoverer implements TypeInformation { return createInfo(parameterizedType.getActualTypeArguments()[1]); } + /* (non-Javadoc) + * @see org.springframework.data.util.TypeInformation#isCollectionLike() + */ + @Override + public boolean isCollectionLike() { + + Class rawType = getType(); + return rawType == null ? null : rawType.isArray() || Iterable.class.isAssignableFrom(rawType); + } + /* (non-Javadoc) * @see org.springframework.data.util.TypeInformation#getComponentType() */ public TypeInformation getComponentType() { - if (!(Map.class.isAssignableFrom(getType()) || Collection.class.isAssignableFrom(getType()))) { + if (!(Map.class.isAssignableFrom(getType()) || isCollectionLike())) { return null; } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeInformation.java b/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeInformation.java index 1ad1a8d85..22b4e1535 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeInformation.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/util/TypeInformation.java @@ -1,5 +1,6 @@ package org.springframework.data.util; +import java.lang.reflect.Array; import java.util.Collection; import java.util.Map; @@ -20,6 +21,15 @@ public interface TypeInformation { * @return */ TypeInformation getProperty(String fieldname); + + /** + * Returns whether the type can be considered a collection, which means it's a container of elements, e.g. a + * {@link Collection} and {@link Array} or anything implementing {@link Iterable}. If this returns {@literal true} you + * can expect {@link #getComponentType()} to return a non-{@literal null} value. + * + * @return + */ + boolean isCollectionLike(); /** * Returns the component type for {@link Collection}s or the key type for {@link Map}s. @@ -27,6 +37,14 @@ public interface TypeInformation { * @return */ TypeInformation getComponentType(); + + /** + * Returns whether the property is a {@link Map}. If this returns {@literal true} you can expect + * {@link #getComponentType()} as well as {@link #getMapValueType()} to return something not {@literal null}. + * + * @return + */ + boolean isMap(); /** * Will return the type of the value in case the underlying type is a {@link Map}.