diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractRelationshipFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractRelationshipFieldAccessor.java index 56aea4bcb..f39872f9f 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractRelationshipFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/AbstractRelationshipFieldAccessor.java @@ -28,6 +28,10 @@ public abstract class AbstractRelationshipFieldAccessor imple }); } + @Override + public boolean isWritable(Field field) { + final FieldAccessor accessor = accessorFor(field); + if (accessor == null) return true; + return accessor.isWriteable(entity); + } + @Override public Object getValue(final Field field) { final FieldAccessor accessor = accessorFor(field); diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/DetachableEntityStateAccessors.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/DetachableEntityStateAccessors.java index dc84c297f..09d277a76 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/DetachableEntityStateAccessors.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/DetachableEntityStateAccessors.java @@ -31,6 +31,11 @@ public class DetachableEntityStateAccessors im this.delegate = delegate; } + @Override + public boolean isWritable(Field field) { + return delegate.isWritable(field); + } + @Override public ENTITY getEntity() { return delegate.getEntity(); @@ -61,7 +66,7 @@ public class DetachableEntityStateAccessors im public Object setValue(final Field field, final Object newVal) { if (!transactionIsRunning()) { final ENTITY entity = getEntity(); - if (!isDirty(field)) { + if (!isDirty(field) && isWritable(field)) { Object existingValue; if (entity.hasUnderlyingNode()) existingValue = unwrap(delegate.getValue(field)); else { diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/EntityStateAccessors.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/EntityStateAccessors.java index 0cf2f003e..f1555cd00 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/EntityStateAccessors.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/EntityStateAccessors.java @@ -18,6 +18,7 @@ public interface EntityStateAccessors { void setNode(Node node); Object getValue(Field field); + boolean isWritable(Field field); Object setValue(Field field, Object newVal); diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/FieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/FieldAccessor.java index 4963e14b7..b3df14ff9 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/FieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/FieldAccessor.java @@ -1,11 +1,10 @@ package org.springframework.datastore.graph.neo4j.fieldaccess; -import org.springframework.datastore.graph.api.NodeBacked; - public interface FieldAccessor { Object setValue(ENTITY entity, Object newVal); Object getValue(ENTITY entity); + boolean isWriteable(ENTITY entity); } diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/IdFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/IdFieldAccessor.java index bed33250c..6c425233a 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/IdFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/IdFieldAccessor.java @@ -17,6 +17,11 @@ public class IdFieldAccessor implements FieldAccessor { this.field = field; } + @Override + public boolean isWriteable(NodeBacked nodeBacked) { + return false; + } + @Override public Object setValue(final NodeBacked nodeBacked, final Object newVal) { return doReturn(null); diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/NodePropertyFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/NodePropertyFieldAccessor.java index 9edd76c62..19c0797c7 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/NodePropertyFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/NodePropertyFieldAccessor.java @@ -17,6 +17,11 @@ public class NodePropertyFieldAccessor implements FieldAccessor return newVal; } + @Override + public boolean isWriteable(NodeBacked nodeBacked) { + return true; + } + @Override public Object getValue(final NodeBacked nodeBacked) { return null; diff --git a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/TraversalFieldAccessor.java b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/TraversalFieldAccessor.java index 0212e5dd7..98dfa77b4 100644 --- a/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/TraversalFieldAccessor.java +++ b/src/main/java/org/springframework/datastore/graph/neo4j/fieldaccess/TraversalFieldAccessor.java @@ -33,6 +33,11 @@ public class TraversalFieldAccessor implements FieldAccessor this.fieldTraversalDescriptionBuilder = createTraversalDescription(graphEntityTraversal); } + @Override + public boolean isWriteable(NodeBacked nodeBacked) { + return false; + } + @Override public Object setValue(final NodeBacked nodeBacked, final Object newVal) { throw new InvalidDataAccessApiUsageException("Cannot set readonly traversal description field " + field);