added writeable check to prevent dirty flushing trying to write on readonly fields

This commit is contained in:
Michael Hunger
2010-09-16 00:22:49 +02:00
parent cdbcd3aeed
commit d85b7bda3f
11 changed files with 50 additions and 4 deletions

View File

@@ -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");

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.");
}

View File

@@ -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;

View File

@@ -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);