DATACMNS-68 - Fixed potential NPE in AbstractPersistentProperty.

Fixed ClassTypeInformation returning correct component types for types implementing or extending a Collection or Map type.
This commit is contained in:
Oliver Gierke
2011-08-31 21:03:58 +02:00
parent 0d83b27f62
commit c57d5246e3
3 changed files with 82 additions and 10 deletions

View File

@@ -47,10 +47,13 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
protected final PersistentEntity<?, P> owner;
private final SimpleTypeHolder simpleTypeHolder;
public AbstractPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, PersistentEntity<?, P> owner, SimpleTypeHolder simpleTypeHolder) {
public AbstractPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, PersistentEntity<?, P> owner,
SimpleTypeHolder simpleTypeHolder) {
Assert.notNull(field);
Assert.notNull(simpleTypeHolder);
Assert.notNull(owner);
this.name = field.getName();
this.rawType = field.getType();
this.information = owner.getTypeInformation().getProperty(this.name);
@@ -144,7 +147,13 @@ public abstract class AbstractPersistentProperty<P extends PersistentProperty<P>
}
public Class<?> getComponentType() {
return isMap() || isCollection() ? information.getComponentType().getType() : null;
if (!isMap() && !isCollection()) {
return null;
}
TypeInformation<?> componentType = information.getComponentType();
return componentType == null ? null : componentType.getType();
}
/* (non-Javadoc)

View File

@@ -18,8 +18,10 @@ package org.springframework.data.util;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Collection;
import java.util.Map;
import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.util.Assert;
/**
@@ -79,19 +81,18 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
return type;
}
/* (non-Javadoc)
* @see org.springframework.data.util.TypeDiscoverer#getComponentType()
*/
/*
* (non-Javadoc)
* @see org.springframework.data.util.TypeDiscoverer#getComponentType()
*/
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public TypeInformation<?> getComponentType() {
if (type.isArray()) {
return createInfo(resolveArrayType(type));
}
TypeVariable<?>[] typeParameters = type.getTypeParameters();
return typeParameters.length > 0 ? new TypeVariableTypeInformation(typeParameters[0], this.getType(), this) : null;
return super.getComponentType();
}
private static Type resolveArrayType(Class<?> type) {

View File

@@ -0,0 +1,62 @@
package org.springframework.data.mapping.model;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.TreeSet;
import org.junit.Test;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.util.ReflectionUtils;
/**
* Unit tests for {@link AbstractPersistentProperty}.
*
* @author Oliver Gierke
*/
public class AbstractPersistentPropertyUnitTests {
/**
* @see DATACMNS-68
* @throws Exception
*/
@Test
public void discoversComponentTypeCorrectly() throws Exception {
BasicPersistentEntity<TestClassComplex, SamplePersistentProperty> entity = new BasicPersistentEntity<TestClassComplex, SamplePersistentProperty>(
ClassTypeInformation.from(TestClassComplex.class));
Field field = ReflectionUtils.findField(TestClassComplex.class, "testClassSet");
SamplePersistentProperty property = new SamplePersistentProperty(field, null, entity, new SimpleTypeHolder());
property.getComponentType();
}
@SuppressWarnings("serial")
class TestClassSet extends TreeSet<Object> {
}
class TestClassComplex {
String id;
TestClassSet testClassSet;
}
class SamplePersistentProperty extends AbstractPersistentProperty<SamplePersistentProperty> {
public SamplePersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
PersistentEntity<?, SamplePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
}
public boolean isIdProperty() {
return false;
}
@Override
protected Association<SamplePersistentProperty> createAssociation() {
return null;
}
}
}