neo4jspring-data-neo4jneo4j-ogmdynamic-propertiesspring-data-neo4j-5

Spring Data Neo4j 5 update dynamic properties


I have the following entity:

@NodeEntity
public class Value {

    @Properties(prefix = "property", allowCast = true)
    private Map<String, Object> properties;

}

I have added the following properties:

Map<String, Object> properties1 = new HashMap<>();
properties.put("key1", "one");
properties.put("key2", "two");

value.setProperties(properties1);

Right now on the database level, I have the Value node with two properties:

property.key1 = "one"
property.key2 = "two"

Now, I'd like to update the properties for this Value node. In order to do this I have created other properties:

Map<String, Object> properties2 = new HashMap<>();
properties.put("key1", "three");

After updating the node on the database level I have the following properties:

property.key1 = "three"
property.key2 = "two"

As you may see, the following approach correctly updated the property with the key1 but doesn't remove the property with the key2.

How to properly update the dynamic properties in order to remove all properties with the keys that are absent in the new properties2 HashMap?

UPDATED

As suggested at the answer below, I use the following code inorder to reuse the same properties from the Value node:

Map<String, Object> oldProperties = value.getProperties();
Map<String, Object> newProperties = extractProperties(properties);

mergeMaps(newProperties, oldProperties);

protected void mergeMaps(Map<String, Object> sourceMap, Map<String, Object> destinationMap) {
    Iterator<Map.Entry<String, Object>> iterator = destinationMap.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry<String, Object> entry = iterator.next();
        String key = entry.getKey();
        Object value = sourceMap.get(key);
        if (value == null) {
            iterator.remove();
        } else {
            entry.setValue(value);
        }
    }
}

but it still doesn't work with the same result as previously - it still doesn't remove the properties from the Neo4j node by the removed keys. What am I doing wrong ?


Solution

  • You can use the standard Map.remove method to remove an entry from the map:

    properties.remove("key2");
    

    Also, you should not be making new Map objects over and over again, just use the one Map and update it.

    UPDATE: That didn't work. But, you can use a Cypher query to remove a property:

    session.query("MATCH (v:Value) REMOVE v.`property.key2`", Collections.emptyMap());