DATACMNS-1139 - AbstractPersistentProperty.getRawType() now correctly resolves generics.

We're now favoring the generic TypeInformation over trying to resolve the property type via field or PropertyDescriptor as only the former does proper generic type resolution.
This commit is contained in:
Oliver Gierke
2017-08-14 13:39:25 +02:00
parent 8638d30a00
commit 766c9078f2
2 changed files with 30 additions and 38 deletions

View File

@@ -62,8 +62,9 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
Assert.notNull(owner, "Owner entity must not be null!");
this.name = field == null ? propertyDescriptor.getName() : field.getName();
this.rawType = field == null ? propertyDescriptor.getPropertyType() : field.getType();
this.information = owner.getTypeInformation().getProperty(this.name);
this.rawType = this.information != null ? information.getType()
: field == null ? propertyDescriptor.getPropertyType() : field.getType();
this.propertyDescriptor = propertyDescriptor;
this.field = field;
this.association = isAssociation() ? createAssociation() : null;

View File

@@ -36,7 +36,6 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.Person;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.ReflectionUtils;
/**
@@ -46,60 +45,50 @@ import org.springframework.util.ReflectionUtils;
*/
public class AbstractPersistentPropertyUnitTests {
TypeInformation<TestClassComplex> typeInfo;
PersistentEntity<TestClassComplex, SamplePersistentProperty> entity;
SimpleTypeHolder typeHolder;
@Before
public void setUp() {
typeInfo = ClassTypeInformation.from(TestClassComplex.class);
entity = new BasicPersistentEntity<TestClassComplex, SamplePersistentProperty>(typeInfo);
typeHolder = new SimpleTypeHolder();
}
@Test // DATACMNS-68
public void discoversComponentTypeCorrectly() throws Exception {
Field field = ReflectionUtils.findField(TestClassComplex.class, "testClassSet");
SamplePersistentProperty property = getProperty(TestClassComplex.class, "testClassSet");
SamplePersistentProperty property = new SamplePersistentProperty(field, null, entity, typeHolder);
property.getComponentType();
}
@Test // DATACMNS-101
public void returnsNestedEntityTypeCorrectly() {
Field field = ReflectionUtils.findField(TestClassComplex.class, "testClassSet");
SamplePersistentProperty property = getProperty(TestClassComplex.class, "testClassSet", null);
SamplePersistentProperty property = new SamplePersistentProperty(field, null, entity, typeHolder);
assertThat(property.getPersistentEntityType().iterator().hasNext(), is(false));
}
@Test // DATACMNS-132
public void isEntityWorksForUntypedMaps() throws Exception {
Field field = ReflectionUtils.findField(TestClassComplex.class, "map");
SamplePersistentProperty property = new SamplePersistentProperty(field, null, entity, typeHolder);
SamplePersistentProperty property = getProperty(TestClassComplex.class, "map", null);
assertThat(property.isEntity(), is(false));
}
@Test // DATACMNS-132
public void isEntityWorksForUntypedCollection() throws Exception {
Field field = ReflectionUtils.findField(TestClassComplex.class, "collection");
SamplePersistentProperty property = new SamplePersistentProperty(field, null, entity, typeHolder);
SamplePersistentProperty property = getProperty(TestClassComplex.class, "collection", null);
assertThat(property.isEntity(), is(false));
}
@Test // DATACMNS-121
public void considersPropertiesEqualIfFieldEquals() {
Field first = ReflectionUtils.findField(FirstConcrete.class, "genericField");
Field second = ReflectionUtils.findField(SecondConcrete.class, "genericField");
SamplePersistentProperty firstProperty = new SamplePersistentProperty(first, null, entity, typeHolder);
SamplePersistentProperty secondProperty = new SamplePersistentProperty(second, null, entity, typeHolder);
SamplePersistentProperty firstProperty = getProperty(FirstConcrete.class, "genericField", null);
SamplePersistentProperty secondProperty = getProperty(SecondConcrete.class, "genericField", null);
assertThat(firstProperty, is(secondProperty));
assertThat(firstProperty.hashCode(), is(secondProperty.hashCode()));
@@ -108,18 +97,15 @@ public class AbstractPersistentPropertyUnitTests {
@Test // DATACMNS-180
public void doesNotConsiderJavaTransientFieldsTransient() {
Field transientField = ReflectionUtils.findField(TestClassComplex.class, "transientField");
PersistentProperty<?> property = getProperty(TestClassComplex.class, "transientField", null);
PersistentProperty<?> property = new SamplePersistentProperty(transientField, null, entity, typeHolder);
assertThat(property.isTransient(), is(false));
}
@Test // DATACMNS-206
public void findsSimpleGettersAndASetters() {
Field field = ReflectionUtils.findField(AccessorTestClass.class, "id");
PersistentProperty<SamplePersistentProperty> property = new SamplePersistentProperty(field, getPropertyDescriptor(
AccessorTestClass.class, "id"), entity, typeHolder);
PersistentProperty<SamplePersistentProperty> property = getProperty(AccessorTestClass.class, "id");
assertThat(property.getGetter(), is(notNullValue()));
assertThat(property.getSetter(), is(notNullValue()));
@@ -128,9 +114,7 @@ public class AbstractPersistentPropertyUnitTests {
@Test // DATACMNS-206
public void doesNotUseInvalidGettersAndASetters() {
Field field = ReflectionUtils.findField(AccessorTestClass.class, "anotherId");
PersistentProperty<SamplePersistentProperty> property = new SamplePersistentProperty(field, getPropertyDescriptor(
AccessorTestClass.class, "anotherId"), entity, typeHolder);
PersistentProperty<SamplePersistentProperty> property = getProperty(AccessorTestClass.class, "anotherId");
assertThat(property.getGetter(), is(nullValue()));
assertThat(property.getSetter(), is(nullValue()));
@@ -139,9 +123,7 @@ public class AbstractPersistentPropertyUnitTests {
@Test // DATACMNS-206
public void usesCustomGetter() {
Field field = ReflectionUtils.findField(AccessorTestClass.class, "yetAnotherId");
PersistentProperty<SamplePersistentProperty> property = new SamplePersistentProperty(field, getPropertyDescriptor(
AccessorTestClass.class, "yetAnotherId"), entity, typeHolder);
PersistentProperty<SamplePersistentProperty> property = getProperty(AccessorTestClass.class, "yetAnotherId");
assertThat(property.getGetter(), is(notNullValue()));
assertThat(property.getSetter(), is(nullValue()));
@@ -150,9 +132,8 @@ public class AbstractPersistentPropertyUnitTests {
@Test // DATACMNS-206
public void usesCustomSetter() {
Field field = ReflectionUtils.findField(AccessorTestClass.class, "yetYetAnotherId");
PersistentProperty<SamplePersistentProperty> property = new SamplePersistentProperty(field, getPropertyDescriptor(
AccessorTestClass.class, "yetYetAnotherId"), entity, typeHolder);
PersistentProperty<SamplePersistentProperty> property = getProperty(AccessorTestClass.class, "yetAnotherId",
getPropertyDescriptor(AccessorTestClass.class, "yetYetAnotherId"));
assertThat(property.getGetter(), is(nullValue()));
assertThat(property.getSetter(), is(notNullValue()));
@@ -161,9 +142,7 @@ public class AbstractPersistentPropertyUnitTests {
@Test // DATACMNS-206
public void returnsNullGetterAndSetterIfNoPropertyDescriptorGiven() {
Field field = ReflectionUtils.findField(AccessorTestClass.class, "id");
PersistentProperty<SamplePersistentProperty> property = new SamplePersistentProperty(field, null, entity,
typeHolder);
PersistentProperty<SamplePersistentProperty> property = getProperty(AccessorTestClass.class, "id", null);
assertThat(property.getGetter(), is(nullValue()));
assertThat(property.getSetter(), is(nullValue()));
@@ -221,13 +200,25 @@ public class AbstractPersistentPropertyUnitTests {
assertThat(property.isEntity(), is(false));
}
@Test // DATACMNS-1139
public void resolvesGenericsForRawType() {
SamplePersistentProperty property = getProperty(FirstConcrete.class, "genericField");
assertThat(property.getRawType(), is(typeCompatibleWith(String.class)));
}
private <T> SamplePersistentProperty getProperty(Class<T> type, String name) {
return getProperty(type, name, getPropertyDescriptor(type, name));
}
private <T> SamplePersistentProperty getProperty(Class<T> type, String name, PropertyDescriptor descriptor) {
BasicPersistentEntity<T, SamplePersistentProperty> entity = new BasicPersistentEntity<T, SamplePersistentProperty>(
ClassTypeInformation.from(type));
Field field = ReflectionUtils.findField(type, name);
return new SamplePersistentProperty(field, null, entity, typeHolder);
return new SamplePersistentProperty(field, descriptor, entity, typeHolder);
}
private static PropertyDescriptor getPropertyDescriptor(Class<?> type, String propertyName) {