added writeable check to prevent dirty flushing trying to write on readonly fields
This commit is contained in:
@@ -28,6 +28,10 @@ public abstract class AbstractRelationshipFieldAccessor<ENTITY,STATE,TARGET,TSTA
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(ENTITY entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected STATE checkUnderlyingNode(ENTITY entity) {
|
||||
if (entity==null) throw new IllegalStateException("Entity is null");
|
||||
|
||||
@@ -76,6 +76,13 @@ public class DefaultEntityStateAccessors<ENTITY extends NodeBacked, STATE> imple
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable(Field field) {
|
||||
final FieldAccessor<ENTITY, ?> accessor = accessorFor(field);
|
||||
if (accessor == null) return true;
|
||||
return accessor.isWriteable(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final Field field) {
|
||||
final FieldAccessor<ENTITY, ?> accessor = accessorFor(field);
|
||||
|
||||
@@ -31,6 +31,11 @@ public class DetachableEntityStateAccessors<ENTITY extends NodeBacked, STATE> 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<ENTITY extends NodeBacked, STATE> 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 {
|
||||
|
||||
@@ -18,6 +18,7 @@ public interface EntityStateAccessors<ENTITY extends NodeBacked> {
|
||||
void setNode(Node node);
|
||||
|
||||
Object getValue(Field field);
|
||||
boolean isWritable(Field field);
|
||||
|
||||
Object setValue(Field field, Object newVal);
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
|
||||
public interface FieldAccessor<ENTITY, TARGET> {
|
||||
|
||||
Object setValue(ENTITY entity, Object newVal);
|
||||
|
||||
Object getValue(ENTITY entity);
|
||||
|
||||
boolean isWriteable(ENTITY entity);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@ public class IdFieldAccessor implements FieldAccessor<NodeBacked, Object> {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(NodeBacked nodeBacked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked nodeBacked, final Object newVal) {
|
||||
return doReturn(null);
|
||||
|
||||
@@ -17,6 +17,11 @@ public class NodePropertyFieldAccessor implements FieldAccessor<NodeBacked, Obje
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(NodeBacked nodeBacked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked nodeBacked, final Object newVal) {
|
||||
nodeBacked.getUnderlyingNode().setProperty(getPropertyName(),newVal);
|
||||
|
||||
@@ -26,6 +26,11 @@ public class OneToNRelationshipEntityFieldAccessor extends AbstractRelationshipF
|
||||
throw new InvalidDataAccessApiUsageException("Cannot set read-only relationship entity field.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(NodeBacked nodeBacked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked entity) {
|
||||
checkUnderlyingNode(entity);
|
||||
|
||||
@@ -15,7 +15,12 @@ public class ReadOnlyOneToNRelationshipFieldAccessor extends OneToNRelationshipF
|
||||
super(type,direction,elementClass, graphDatabaseContext);
|
||||
}
|
||||
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
@Override
|
||||
public boolean isWriteable(NodeBacked nodeBacked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
throw new InvalidDataAccessApiUsageException("Cannot set read-only relationship entity field.");
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ public class TransientFieldAccessor implements FieldAccessor<NodeBacked, Object>
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWriteable(NodeBacked nodeBacked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked nodeBacked) {
|
||||
return null;
|
||||
|
||||
@@ -33,6 +33,11 @@ public class TraversalFieldAccessor implements FieldAccessor<NodeBacked, Object>
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user