Search code examples
neo4jcypherspring-data-neo4jneo4j-ogmspring-data-neo4j-5

Spring Data Neo4j 5 node/relationship labels and inheritance


I have the following Spring Data Neo4j 5 entity:

@NodeEntity
public class Value extends Flaggable {

    @Index(unique = true)
    private Long id;

    private String name;

    private String description;

    @Index(unique = false)
    private Object value;

}

Right now the Value nodes have the following labels:

MATCH(n:Value) RETURN labels(n) LIMITS 1

["BaseEntity", "Subscribable", "Flaggable", "Likeable", "Value"]

In some cases, according to my project requirements I need to extend the Value node with additional properties, like for example weight and size.

I don't want to change the existing Value class and want to introduce a new - inherited one, for example:

@NodeEntity
public class WeightedValue extends Value{

    private Long weight;

    private Long size;

}

I have a question, will the following query MATCH(n:Value) RETURN n return also the instances of WeightedValue ?

Will it be possible to search WeightedValue nodes(by Value label) by the following query?

MATCH(n:Value) WHERE n.size > 1000 RETURN n

Will the approach above work for @RelationshipEntity and inheritance? So is it possible to use inheritance for @RelationshipEntity and how to keep the same label(for example HAS_VALUE_ON) for the base and inherited classes, for example:

@RelationshipEntity(type = "HAS_VALUE_ON")
public class RelationshipValue {

    @Id
    @GeneratedValue
    private Long id;

    @StartNode
    private Decision decision;

    @EndNode
    private Characteristic characteristic;

}

@RelationshipEntity(type = "HAS_VALUE_ON")
public class WeightedRelationshipValue extends RelationshipValue {

    private Long weight;

    private Long size; 

}

Solution

  • For the first part of your question, nodes created by WeightedValue extends Value class would have both the Value and WeightedValue labels (you can make it so it doesn't have the super class if you wanted). So, as long as ALL WeightedValue nodes are Value nodes, then you can MATCH on Value nodes.

    Also, in your question you ask if a Cypher MATCH query will work, but I wanted to ensure you weren't assuming the behind-the-scenes query that SDN might turn your repository query in to (i.e. findAll()). I am not certain, at all, but it is possible that SDN might convert something such as weightedValueRepo.findAll() into something like: MATCH (n:Value:WeightedValue) return n; In Cypher this returns the node thus all it's properties. However, if in Java you used List<Value> values = valueRepo.findAll() keep in mind that a Value object may not have all the same Java/class properties as WeightedValue objects.

    So, in Cypher matching/querying on the Value label can get you access to the entire node (including properties defined only in WeightedValue objects, finding/matching via SDN may not because the OGM has to map the properties of a node to a class (and that super class doesn't generally have the same properties as it's subclasses).

    For the second part, a single Relationship, I believe, has only a single type and does not work like labels, where an entity can have multiple. You can create multiple relationships of different types between the same nodes, though. I am uncertain if one @RelationshipEntity extends another if SDN would create both rels or not. Maybe you can try it and let me know. :slightly_smiling_face: