neo4j-ogm: @Id does not work with @Convert

We have a proprietary unique id on all entities in our application, and we would like to use it as our primary id instead of the old Long @GraphId. Unfortunately, OGM fails when we have both @Id and @Convert with a converter on a field.

Expected Behavior

The Id should be recognized for adding and updating purposes.

Current Behavior

org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for id

Possible Solution

Because of the converter, the primaryIdToNativeId map in MappingContext ends up with copies of the same object with a LabelPrimaryId key using both the original type and the converted type (in this case, it’s a String). There should probably be something to make sure only the converted or original type ends up in the MappingContext.

Steps to Reproduce (for bugs)

Create a wrapper Id object:

class PrimaryUuid {
  private UUID id;
  private PrimaryUuid() {
    id = UUID.randomUuid();
  }
  public PrimaryUuid(String s) {
    id = UUID.fromString(s);
  }
  public static PrimaryUuid getPrimaryUuid() { return new PrimaryUuid(); }
  //...hashcode, equals, toString, etc.
}

Create a Converter:

public class PrimaryUuidConverter implements AttributeConverter<PrimaryUuid, String> {
    public String toGraphProperty(PrimaryUuid value) {
        return value.toString();
    }
    public PrimaryUuid toEntityAttribute(String s) {
        return new PrimaryUuid(s);
    }
}

Add both as an @Id to an Entity:

public class Entity {
  @Id
  @Convert(converter = PrimaryUuidConverter.class)
  private PrimaryUuid id;

  // ...gettters, setters, hashcode, equals, etc.
}

Create subclasses with relationships

public class A extends Entity {
  @Relationship(type = "A_RELATIONSHIP")
  private B b;
// ..relationships and properties, getters, setters, etc.
}
public class B extends Entity {
  @Relationship(type = "A_RELATIONSHIP", direction = Relationship.INCOMING)
  private A a;
// ..relationships and properties, getters, setters, etc.
}

Add, load and update objects with neo4j database. Eventually you will get: org.neo4j.driver.v1.exceptions.ClientException: Cannot merge node using null property value for id

Context

Proprietary Id object with converter that we want to use as @Id so we can remove unnecessary and deprecated @GraphId.

Your Environment

  • OGM Version used: 3.1.0
  • Java Version used: 8u162b12
  • Neo4J Version used: 3.3.2
  • Bolt Driver Version used (if applicable):
  • Operating System and Version:
  • Link to your project:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 22

Commits related to this issue

Most upvoted comments

I added the test from the related PR.

The issues is fixed in 3.1.5 and 3.2.x (the later not yet released).

I’ll investigate the issue on the SDN site, @FrozenGenis. This here can be considered fixed.

If you want to use custom ids the attribute should have a @GeneratedValue annotation. Additional keep in mind that the name id is reserved for OGM internal id handling. Please use another name for the attribute. Feel free to close this issue if this solves your problem. Sample:

@Id
@GeneratedValue(strategy = MyGenerator.class)
@Convert(MyConverter.class)
private UUID myId;

With generator:

public class MyGenerator implements IdStrategy {
	@Override public Object generateId(Object entity) {
		return UUID.randomUUID();
	}
}

and converter

public class MyConverter implements AttributeConverter <UUID, String>{
	@Override public String toGraphProperty(UUID value) {
		return value == null ? null : value.toString();
	}

	@Override public UUID toEntityAttribute(String value) {
		return value == null ? null :UUID.fromString(value);
	}
}