Search code examples
neo4jspring-dataspring-data-neo4jspring-data-neo4j-4neo4j-ogm

Neo4j-OGM/Spring-Data-Neo4j: Migrate property type from Integer to String


In a large database I have to change the data type of a property for a type of nodes from Integer to String (i.e. 42 to "42") in order to also support non-numerical IDs.

I've managed to do the migration itself and the property now has the expected type in the database. I have verified this using the Neo4j-Browsers ability to show the query result as JSON:

"graph": {
    "nodes": [
        {
            "id": "4190",
            "labels": [
                "MyEntity"
                ],
            "properties": {
                "id": "225"
            }
        }
    }

Note that the "id" property is different from the node's own (numerical) id.

In the corresponding Spring-Data-Neo4j 4app, I adjusted the type of the corresponding property from Integer to String as well. I expected that to be enough, however upon first loading an affected entity I now receive:

org.neo4j.ogm.exception.MappingException: Error mapping GraphModel to instance of com.example.MyEntity
[...]
Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set java.lang.String field de.moneysoft.core.model.base.UriEntity.transfermarktId to java.lang.Integer
    at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:43)
    at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:68)
    at org.neo4j.ogm.context.GraphEntityMapper.writeProperty(GraphEntityMapper.java:232)
    at org.neo4j.ogm.context.GraphEntityMapper.setProperties(GraphEntityMapper.java:184)
    at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:151)
    at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:135)
    ... 122 common frames omitted
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.example.MyEntity.id to java.lang.Integer
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:764)
    at org.neo4j.ogm.entity.io.FieldWriter.write(FieldWriter.java:41)
    ... 127 common frames omitted

I am not aware of Neo4j-OGM storing any kind of model or datatype (at least I don't see it in the graph). Why does it still believe that my property is an Integer?

Edit: Node Entity after migration:

@NodeEntity
public class MyEntity
{
    @Property
    protected String name;
    @Property
    private String id;
}

I am not aware of any other relevant code.


Solution

  • Well, if the error you see looks implausible, it probably is. After a good nights sleep, I realized that I had connected to the wrong database instance: Not the one that was migrated and that I was looking at in the browser, but another one that contained an unmigrated state.

    After connecting to the correct instance, everything worked as expected!