Polyakoff Polyakoff - 1 month ago 12
Java Question

How to code the hierarchical relationship to the node of the same type properly in spring data neo4j?

I have a tree data structure I'd like to store using Neo4j.

There is a parent node

:CodeSet
, which is always the root of the tree and a child nodes
:Node
, which themselves can have child nodes of the same type. They are connected with relationship of type
:SUBTREE_OF
as follows: tree data structure

The parent node is displayed in red and it itself has a parent displayed in green.

As soon as parent node and child nodes have some common data, I created an abstract class:

public abstract class AbstractNode {
private Long id;
@NotEmpty
private String code;
@Relationship(type = "SUBTREE_OF", direction = Relationship.INCOMING)
private Set<Node> children;

<getters & setters omitted>
}


Class for the parent node:

public class CodeSet extends AbstractNode {
@Relationship(type = "SUBTREE_OF", direction = Relationship.OUTGOING)
private Application parent;

<getters and setters omitted>
}


Class for the child node:

public class Node extends AbstractNode {
@NotEmpty
private String description;
@NotEmpty
private String type;
@NotEmpty
private String name;
@NotNull
@Relationship(type = "SUBTREE_OF", direction = Relationship.OUTGOING)
private AbstractNode parent;

<getters and setters omitted>
}


What I need is just making a child node update. I use the following method at my service layer:

public Node update(Node node, Long nodeId) throws EntityNotFoundException {
Node updated = findById(nodeId, 0);
updated.setDescription(node.getDescription());
updated.setType(node.getType());
updated.setName(node.getName());
updated.setCode(node.getCode());
nodeRepository.save(updated);
return updated;
}


With this I got the following result:
result of node update
The relationship is broken. I also tried out to specify
depth=1
at
findById
method parameter, but that resulted in wrong relationships once again:
enter image description here

After that I tried out modifying bi-directional relationship in my classes to uni-directional so as only one class has an annotated with
@Relatinship
field pointing to another, but that did not help either.

How to make this work?

Answer

Was resolved by updating the save operation in the service method:

public Node update(Node node, Long nodeId) throws EntityNotFoundException {
    Node updated = findById(nodeId, 0);
    updated.setDescription(node.getDescription());
    updated.setType(node.getType());
    updated.setName(node.getName());
    updated.setCode(node.getCode());
    //added param depth=0 here
    nodeRepository.save(updated, 0);
    return updated;
}