6
votes

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?

2
Hi, which version of SDN are you using please?Vince
@Vince it was org.springframework.data:spring-data-neo4j:4.1.2.RELEASEPoliakoff

2 Answers

6
votes

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;
}
0
votes

Maybe there is a problem with your definition of relationship in abstract class. Children's nodes inherit INCOMING relationships too, so when you update using depth 1 relationships are bilateral.