Does remove attributes?

I'm working on a new relational database (not my choice) and at the point where I have to update a record I am calling the save method on the repository - which is dutifully writing both the null and non-null attributes values alike to the database. The behaviour that is required is to only update the non-null values supplied by the client and ignore other attributes with a null value in the update object supplied by the client leaving them unchanged in the database. This behaviour is useful for the common case where the client wants to update the value of a single attribute without affecting any other attribute values in the record. It looks like the solution is to read the value from the database into a parking object, copy over the non-null attribute values from the update request, and then save the whole thing again.

I would like to build a case that this would be simpler to implement in Neo4j. However, the documentation is far from clear what a does when you call save().

Does calling save and presenting a new node object remove existing attributes unmentioned in the new object? Is there a way to say "save this node, updating and creating attribute values as necessary but preserving any existing attributes"? It would be really handy if there is a way to do this and a significant advantage over the three point turn I am about to continue writing as soon as I have posted this question.

Hi Paul, and the underlying infrastructure will remove properties with a literal value of null on the entity.

We have an internal API to add some kind of write protection for the whole entity class, but not single properties. That could be extended, but at the moment, I don't have too much time for that.

Feel free to raise at least a feature request for that on GitHub - neo4j/neo4j-ogm: Java Object-Graph Mapping Library for Neo4j.


@michael.simons Thanks for your response Michael. Surprisingly other databases have no 'update non-nulls' method. It is strange because it is common when responding to to perform an update of all non-null attributes, so I'm fairly sure it would get used if implemented.

In the mean time I'll probably do something like:

GraphDatabaseService db = new GraphDatabaseFactory().newEmbeddedDatabase( databaseDirectory );
// find the node somehow
Node foundNode = ...
try ( Transaction tx = db.beginTx())
    for (String key : attributes.keySet())
    	if (attributes.get(key) != null)
    foundNode.setProperty(key, attributes.get(key));