Search code examples
neo4jspring-data-neo4jneo4j-ogm

Custom datatype or HashMap for relationship between nodes in Neo4J


Is it possible to have value of a relationship between node as a user-defined class or it should be a primitive datatype. For example:

@RelationshipEntity(type = "ALIGNED_WITH")
public class AlignedWith {

    @GraphId
    private Long id;

    private Set<DeptEndorsement> deptEndorsement = new HashSet<>();

    @StartNode
    private Term startTerm;

    @EndNode
    private Term endTerm;

    // getters and setters

}


public class DeptEndorsement {

    private String deptName;
    private Integer endorsementCount;

    // getters and setters

}


@NodeEntity
public class Term {

    @GraphId
    private Long id;

    private String termName;

    @Relationship(type = "ALIGNED_WITH", direction = Relationship.OUTGOING)
    private List<AlignedWith> alignedWith = new ArrayList<>();

    public void addAlignedWith(AlignedWith alignedWith) {
        this.alignedWith.add(alignedWith);
    }

    // getters and setters

}

If you observe DeptEndorsement is a custom class which I want as value for relationship AlignedWith

Or, is it possible to have a HashMap (example: HashMap<String, Integer>) as the value for the relationship between nodes?


Solution

  • These are my finding for this question, supported datatypes in Neo4J are:

    Boolean, Long, Double, String, List. Types that can be type casted are Short, Integer, Float (though you need to specify that you allow casting, check below if condition) Ref. MapCompositeConverter.java

    Below condition was responsible to check if the type is supported by Neo4J or not, through in my case I did not provide allowCast to be true and thus java.lang.Integer was not castable:

    if (isCypherType(entryValue) || (allowCast && canCastType(entryValue)))
    
    private boolean isCypherType(Object entryValue) {
        return cypherTypes.contains(entryValue.getClass()) || List.class.isAssignableFrom(entryValue.getClass());
    }
    

    I changed from java.lang.Integer to java.lang.Long and everything works fine. You can not use custom datatype as in my case DeptEndorsement

    Below is how my properties look like for a relationship.

    @Properties
    private Map<String, Long> deptEndorsement = new HashMap<>();
    

    @Properties annotation is available in neo4j-ogm-core 3.0.0+ Ref: Compatibility