diff --git a/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java b/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java index 11a3ae774..233a7eadf 100644 --- a/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java +++ b/src/main/java/org/springframework/data/util/ParameterizedTypeInformation.java @@ -156,6 +156,17 @@ class ParameterizedTypeInformation extends ParentTypeAwareTypeInformation @Override @Nullable protected TypeInformation doGetComponentType() { + + boolean isCustomMapImplementation = isMap() && !getType().equals(Map.class); + + if (isCustomMapImplementation) { + return getRequiredSuperTypeInformation(Map.class).getComponentType(); + } + + if (isCollectionLike() && !getType().getPackage().getName().startsWith("java.")) { + return getRequiredSuperTypeInformation(Iterable.class).getComponentType(); + } + return createInfo(type.getActualTypeArguments()[0]); } diff --git a/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java b/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java index ea8882198..55c00bb0a 100755 --- a/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java +++ b/src/test/java/org/springframework/data/repository/util/QueryExecutionConvertersUnitTests.java @@ -264,8 +264,8 @@ class QueryExecutionConvertersUnitTests { Method method = Sample.class.getMethod("pages"); TypeInformation returnType = ClassTypeInformation.fromReturnTypeOf(method); - assertThat(QueryExecutionConverters.unwrapWrapperTypes(returnType)) - .isEqualTo(ClassTypeInformation.from(String.class)); + assertThat(QueryExecutionConverters.unwrapWrapperTypes(returnType).getType()) + .isEqualTo(String.class); } @Test // DATACMNS-983 diff --git a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java index 53d7d7397..98e87612d 100755 --- a/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java +++ b/src/test/java/org/springframework/data/util/ClassTypeInformationUnitTests.java @@ -443,6 +443,32 @@ public class ClassTypeInformationUnitTests { assertThat(specialized.getProperty("root").getType()).isEqualTo(Aggregate.class); } + @Test // DATACMNS-1828 + void discoversMapKeyAndValueTypeFromTypedMap() { + + TypeInformation information = from(TypeWithTypedMap.class); + + TypeInformation typedMap = information.getProperty("typedMap"); + + assertThat(typedMap.getType()).isEqualTo(StringKeyMap.class); + assertThat(typedMap.isMap()).isTrue(); + assertThat(typedMap.getRequiredComponentType().getType()).isEqualTo(String.class); + assertThat(typedMap.getMapValueType().getType()).isEqualTo(Long.class); + + TypeInformation longMultiValueMap = information.getProperty("longMultiValueMap"); + + assertThat(longMultiValueMap.getType()).isEqualTo(MultiValueMap.class); + assertThat(longMultiValueMap.getRequiredComponentType().getType()).isEqualTo(String.class); + assertThat(longMultiValueMap.getMapValueType().getType()).isEqualTo(List.class); + assertThat(longMultiValueMap.getMapValueType().getRequiredActualType().getType()).isEqualTo(Long.class); + + TypeInformation justMap = information.getProperty("justMap"); + + assertThat(justMap.getType()).isEqualTo(Map.class); + assertThat(justMap.getRequiredComponentType().getType()).isEqualTo(String.class); + assertThat(justMap.getMapValueType().getType()).isEqualTo(Long.class); + } + static class StringMapContainer extends MapContainer { } @@ -681,4 +707,15 @@ public class ClassTypeInformationUnitTests { // A domain type partially binding generics static class GenericEvent extends DomainEvent {} + + // DATACMNS-1828 + interface StringKeyMap extends Map {} + + interface MultiValueMap extends Map> {} + + static class TypeWithTypedMap { + StringKeyMap typedMap; + MultiValueMap longMultiValueMap; + Map justMap; + } }