Browse Source

Include inherited non-Kotlin properties in `KotlinBeanInfoFactory`.

We now include properties from non-Kotlin supertypes if the supertype is not a Kotlin type and not Object.

Closes #2994
pull/2996/head
Mark Paluch 2 years ago
parent
commit
8a679156e0
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 21
      src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java
  2. 25
      src/test/kotlin/org/springframework/data/util/KotlinBeanInfoFactoryUnitTests.kt

21
src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java

@ -28,10 +28,12 @@ import java.beans.IntrospectionException; @@ -28,10 +28,12 @@ import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.beans.BeanInfoFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.KotlinDetector;
import org.springframework.core.Ordered;
@ -57,7 +59,7 @@ public class KotlinBeanInfoFactory implements BeanInfoFactory, Ordered { @@ -57,7 +59,7 @@ public class KotlinBeanInfoFactory implements BeanInfoFactory, Ordered {
}
KClass<?> kotlinClass = JvmClassMappingKt.getKotlinClass(beanClass);
List<PropertyDescriptor> pds = new ArrayList<>();
Set<PropertyDescriptor> pds = new LinkedHashSet<>();
for (KCallable<?> member : kotlinClass.getMembers()) {
@ -69,6 +71,19 @@ public class KotlinBeanInfoFactory implements BeanInfoFactory, Ordered { @@ -69,6 +71,19 @@ public class KotlinBeanInfoFactory implements BeanInfoFactory, Ordered {
pds.add(new PropertyDescriptor(property.getName(), getter, setter));
}
}
Class<?> javaClass = beanClass;
do {
javaClass = javaClass.getSuperclass();
} while (KotlinDetector.isKotlinType(javaClass));
if (javaClass != Object.class) {
PropertyDescriptor[] javaPropertyDescriptors = BeanUtils.getPropertyDescriptors(javaClass);
pds.addAll(Arrays.asList(javaPropertyDescriptors));
}
return new SimpleBeanInfo() {
@Override
public BeanDescriptor getBeanDescriptor() {

25
src/test/kotlin/org/springframework/data/util/KotlinBeanInfoFactoryUnitTests.kt

@ -18,6 +18,9 @@ package org.springframework.data.util @@ -18,6 +18,9 @@ package org.springframework.data.util
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.BeanUtils
import org.springframework.data.repository.Repository
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport
import org.springframework.data.repository.core.support.RepositoryFactorySupport
/**
* Unit tests for [KotlinBeanInfoFactory].
@ -81,6 +84,14 @@ class KotlinBeanInfoFactoryUnitTests { @@ -81,6 +84,14 @@ class KotlinBeanInfoFactoryUnitTests {
assertThat(pds).extracting("name").contains("ordinal")
}
@Test // GH-2994
internal fun includesPropertiesFromJavaSupertypes() {
val pds = BeanUtils.getPropertyDescriptors(MyRepositoryFactoryBeanImpl::class.java)
assertThat(pds).extracting("name").contains("myQueryLookupStrategyKey", "repositoryBaseClass")
}
data class SimpleDataClass(val id: String, var name: String)
@JvmInline
@ -98,4 +109,18 @@ class KotlinBeanInfoFactoryUnitTests { @@ -98,4 +109,18 @@ class KotlinBeanInfoFactoryUnitTests {
Foo, Bar
}
class MyRepositoryFactoryBeanImpl<R, E, I>(repository: Class<R>) : RepositoryFactoryBeanSupport<R, E, I>(repository)
where R : Repository<E, I>, E : Any, I : Any {
private var myQueryLookupStrategyKey: String
get() = ""
set(value) {
}
override fun createRepositoryFactory(): RepositoryFactorySupport {
throw UnsupportedOperationException()
}
}
}

Loading…
Cancel
Save