From 1eeef23fd9e41e5cbe9fa81a1561a42dbe57fade Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 22 Mar 2021 10:04:29 +0100 Subject: [PATCH] Fix Kotlin copy method assignability check. We now resolve only the raw class when checking if a primary constructor argument is assignable to method parameters of the synthetic copy method. Previously we used ResolvableType's assignability check which considered generic type arguments. As the type resolution between the KType and copy method type is not symmetric, the check only succeeded in cases where both types could be resolved to the same type/assignable type. Using projections or Any caused asymmetric resolution and therefor the assignability check returned non-assignable. Closes #2336. --- .../data/mapping/model/KotlinCopyMethod.java | 3 ++- .../data/mapping/model/KotlinCopyMethodUnitTests.java | 7 +++---- .../springframework/data/mapping/model/DataClasses.kt | 9 +++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java index b6cf9f7fa..ca1b42688 100644 --- a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java +++ b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java @@ -278,7 +278,8 @@ class KotlinCopyMethod { Type parameterType = ReflectJvmMapping.getJavaType(source); - return ResolvableType.forClass(target).isAssignableFrom(ResolvableType.forType(parameterType)); + Class rawClass = ResolvableType.forType(parameterType).getRawClass(); + return rawClass == null || target.isAssignableFrom(rawClass); } /** diff --git a/src/test/java/org/springframework/data/mapping/model/KotlinCopyMethodUnitTests.java b/src/test/java/org/springframework/data/mapping/model/KotlinCopyMethodUnitTests.java index 2332b5564..f6937aa37 100644 --- a/src/test/java/org/springframework/data/mapping/model/KotlinCopyMethodUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/model/KotlinCopyMethodUnitTests.java @@ -73,11 +73,10 @@ class KotlinCopyMethodUnitTests { .isTrue(); } - @Test // #2324 + @Test // #2324, #2336 void shouldDetermineCopyMethodForParametrizedType() { - Optional copyMethod = KotlinCopyMethod.findCopyMethod(ImmutableKotlinPerson.class); - - assertThat(copyMethod).isPresent(); + assertThat(KotlinCopyMethod.findCopyMethod(ImmutableKotlinPerson.class)).isPresent(); + assertThat(KotlinCopyMethod.findCopyMethod(DataClassWithParametrizedCollections.class)).isPresent(); } } diff --git a/src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt b/src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt index 3083bf883..9166082e5 100644 --- a/src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt +++ b/src/test/kotlin/org/springframework/data/mapping/model/DataClasses.kt @@ -65,3 +65,12 @@ data class ImmutableKotlinPerson( @Id val name: String, val wasOnboardedBy: List ) + +data class DataClassWithParametrizedCollections( + val id: String? = null, + val flags: Map, + val stringStringFlags: Map, + val parametrized: List, + val anyList: List<*> +) +