How to correctly encode a hierarchical relationship to a node of the same type in spring neo4j data?

I have a tree data structure that I would like to store using Neo4j.

There is a parent node :CodeSet , which is always the root of the tree and child nodes :Node , which themselves can have child nodes of the same type. They are associated with a relation 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 the parent node and the child nodes have some data in common, 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 parent node:

 public class CodeSet extends AbstractNode { @Relationship(type = "SUBTREE_OF", direction = Relationship.OUTGOING) private Application parent; <getters and setters omitted> } 

Class for 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> } 

I only need to do an update for the child node. I use the following method at my service level:

 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: node update result Relations are broken. I also tried to specify depth=1 in the parameter of the findById method, but this again led to the wrong relationship: enter image description here

After that, I tried changing the bi-directional relationship in my classes to unidirectional, since only one class has an annotated @Relatinship field pointing to another, but that also did not help.

How to do it?

+5
source share
2 answers

It 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; } 
+5
source

There may be a problem with your definition of a relation in an abstract class. Children nodes also inherit the INCOMING relationships, so when you update relationships of depth 1, they are two-way.

0
source

Source: https://habr.com/ru/post/1257808/


All Articles