DATAGRAPH-487 - Handle unique fields that have to be converted correctly

This commit is contained in:
Michael Hunger
2014-06-30 12:13:40 +02:00
parent 83a8fda57b
commit 5013fc76a1
8 changed files with 36 additions and 20 deletions

View File

@@ -82,6 +82,7 @@
<bean id="entityStateHandler" class="org.springframework.data.neo4j.support.mapping.EntityStateHandler">
<constructor-arg ref="mappingContext"/>
<constructor-arg ref="graphDatabase"/>
<constructor-arg ref="conversionService"/>
</bean>
<bean id="graphDatabase" class="org.springframework.data.neo4j.support.DelegatingGraphDatabase">
<constructor-arg ref="graphDatabaseService"/>

View File

@@ -54,7 +54,9 @@
<bean id="entityStateHandler" class="org.springframework.data.neo4j.support.mapping.EntityStateHandler">
<constructor-arg ref="mappingContext"/>
<constructor-arg ref="graphDatabase"/>
<constructor-arg ref="conversionService"/>
</bean>
<bean id="conversionService" class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
<bean id="relationshipEntityInstantiator" class="org.springframework.data.neo4j.support.relationship.RelationshipEntityInstantiator">
<constructor-arg ref="entityStateHandler"/>
</bean>

View File

@@ -60,18 +60,15 @@ public class GenericNodePropertyFieldAccessorFactory implements FieldAccessorFac
@Override
public Object setValue(final Object entity, final Object newVal, MappingPolicy mappingPolicy) {
Object value = propertyConverter.isObjectOrSupportedType(newVal) ? newVal : propertyConverter.serializePropertyValue(newVal);
Object value = propertyConverter.serializeIfNotBuiltIn(newVal);
super.setValue(entity, value, mappingPolicy);
return newVal;
}
@Override
public Object doGetValue(final Object entity) {
Object ret = super.doGetValue(entity);
if (propertyConverter.isObjectOrSupportedType(ret)) {
return ret;
}
return propertyConverter.deserializePropertyValue(ret);
Object value = super.doGetValue(entity);
return propertyConverter.deserializeIfNotBuiltIn(value);
}
@Override

View File

@@ -32,22 +32,25 @@ public class PropertyConverter {
private final ConversionService conversionService;
private final Neo4jPersistentProperty property;
private final TypeInformation<?> typeInformation;
private final Class<?> targetType;
private final Class<?> propertyType;
private final boolean userDefinedPropertyType;
public PropertyConverter(ConversionService conversionService, Neo4jPersistentProperty property) {
this.conversionService = conversionService;
this.property = property;
this.typeInformation = property.getTypeInformation();
targetType = property.getPropertyType();
Class<?> configuredPropertyType = property.getPropertyType();
userDefinedPropertyType = configuredPropertyType != null;
propertyType = userDefinedPropertyType ? configuredPropertyType : Neo4jPersistentProperty.DEFAULT_NEO4J_PROPERTY_TYPE;
}
public Object serializePropertyValue(final Object newVal) {
if (newVal == null) return null;
final TypeInformation<?> typeInformation = property.getTypeInformation();
if (typeInformation.isCollectionLike()) {
return serializeCollection(newVal, conversionService, typeInformation, targetType);
return serializeCollection(newVal, conversionService, typeInformation, propertyType);
}
return conversionService.convert(newVal, targetType);
return conversionService.convert(newVal, propertyType);
}
public Object deserializePropertyValue(final Object newVal) {
@@ -95,15 +98,16 @@ public class PropertyConverter {
}
}
boolean isObjectOrSupportedType(final Object value) {
private boolean isObjectOrSupportedType(final Object value) {
return property.getType().equals(Object.class) && property.isNeo4jPropertyValue(value);
}
public Object deserializeIfNotBuiltIn(Object ret) {
if (isObjectOrSupportedType(ret)) {
if (!userDefinedPropertyType && isObjectOrSupportedType(ret)) {
return ret;
} else {
return deserializePropertyValue(ret);
}
return deserializePropertyValue(ret);
}
public Object serializeIfNotBuiltIn(Object newVal) {

View File

@@ -27,6 +27,8 @@ import org.springframework.data.mapping.PersistentProperty;
*/
public interface Neo4jPersistentProperty extends PersistentProperty<Neo4jPersistentProperty> {
Class<?> DEFAULT_NEO4J_PROPERTY_TYPE = String.class;
/**
* Returns whether the property represents a relationship. If this returns {@literal true}, clients can expect
* {@link #getRelationshipInfo()} to return a non-{@literal null} value.

View File

@@ -54,7 +54,7 @@ abstract class IndexBasedStartClause extends StartClause {
if (property.isNeo4jPropertyType() && property.isNeo4jPropertyValue(value)) return value;
PropertyConverter converter = new PropertyConverter(template.getConversionService(), property);
return converter.serializePropertyValue(value);
return converter.serializeIfNotBuiltIn(value);
}
protected Map<Parameter,PartInfo> findMyParameters(Set<Parameter> parameters) {

View File

@@ -117,8 +117,8 @@ class WhereClause {
protected Object convertValue(PartInfo partInfo, Object value) {
if (EnumSet.of(Type.CONTAINING, Type.STARTING_WITH, Type.ENDING_WITH).contains(type))
return QueryTemplates.formatExpression(this.partInfo, value);
else if (propertyConverter!=null) {
return propertyConverter.serializePropertyValue(value);
else if (propertyConverter!=null ) {
return propertyConverter.serializeIfNotBuiltIn(value);
}
return value;
}

View File

@@ -78,8 +78,8 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
super(field, propertyDescriptor, owner, simpleTypeHolder);
this.hash = field == null ? propertyDescriptor.hashCode() : field.hashCode();
this.relationshipInfo = extractRelationshipInfo(field, ctx);
this.propertyType = extractPropertyType();
this.isNeo4jEntityType = isNeo4jPropertyType(getType());
this.propertyType = extractPropertyType();
this.neo4jPropertyName = createNeo4jPropertyName();
this.indexInfo = extractIndexInfo();
this.isIdProperty = super.isIdProperty() || getAnnotation(GraphId.class) != null;
@@ -97,7 +97,7 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
private Class<?> extractPropertyType() {
final GraphProperty graphProperty = getAnnotation(GraphProperty.class);
if (graphProperty==null) return String.class;
if (graphProperty==null) return null;
return graphProperty.propertyType();
}
@@ -196,9 +196,14 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
return String.format("%s.%s", entityClass.getType().getSimpleName(), getName());
}
public boolean mustConvert() {
return !isNeo4jPropertyType() || propertyType != null;
}
public boolean isSerializablePropertyField(final ConversionService conversionService) {
if (isRelationship()) return false;
if (!mustConvert()) return false;
final Class<?> type = getType();
if (getTypeInformation().isCollectionLike()) {
return isConvertible(conversionService, getComponentType());
@@ -207,7 +212,12 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
}
private boolean isConvertible(ConversionService conversionService, Class<?> type) {
return conversionService.canConvert(type, propertyType) && conversionService.canConvert(propertyType, type);
Class targetType = getPropertyTypeOrDefault();
return conversionService.canConvert(type, targetType) && conversionService.canConvert(targetType, type);
}
private Class<?> getPropertyTypeOrDefault() {
return propertyType == null ? DEFAULT_NEO4J_PROPERTY_TYPE : propertyType;
}
@Override
@@ -238,7 +248,7 @@ class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4
@Override
public boolean isNeo4jPropertyValue(Object value) {
if (value == null || value.getClass().isArray()) {
if (value == null) {
return false;
}
return isNeo4jPropertyType(value.getClass());