0

I've been trying to represent a directed graph using neo4j entities. Working on spring-data-neo4j 4.1.0.BUILD-SNAPSHOT

In my scenario there is a Node which represents a generic graph node, and NodeWithScore which inherits from Node and contains some additional data. All the nodes in the graph are connected to exactly one NodeWithScore.

I've used the following mapping:

@NodeEntity
@Setter
@Getter
@NoArgsConstructor
public class Node {

    @GraphId
    private Long id;

    private String name;

    @Relationship(type = "SCORE")
    private NodeWithScore nodeWithScore;

    @Relationship(type = "CHILD")
    private Set<Node> children;

    @Override
    public String toString()  {
        return String.format("%s -> %s", name,
                children == null ? "[]" : children.stream().map(Node::getName).collect(toList()));
    }

}

and

@NodeEntity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class NodeWithScore extends Node {

    protected Double score;

}

When calling the following code:

Node a = new Node();
a.setName("A");
Node b = new Node();
b.setName("B");
NodeWithScore c = new NodeWithScore();
c.setName("C");

a.setChildren(ImmutableSet.of(b));
b.setChildren(ImmutableSet.of(c));
a.setNodeWithScore(c);
b.setNodeWithScore(c);
c.setNodeWithScore(c);

session.save(a);

everything works as expected - node A has a single child B, which in turn has a single child C, and all three are connected through a SCORE relationship with node C.

And obviously, if in the next line I call:

ImmutableSet.of(a, b, c).forEach(System.out::println);

the result will be:

A -> [B]
B -> [C]
C -> []

However, if in the very next line I try to call:

session.loadAll(Node.class).forEach(System.out::println);

I'm getting the following result:

A -> [B, C]
B -> [C]
C -> [B]

Please let me know if it's a bug with neo4j, or am I doing something wrong.

Luanne
  • 19,145
  • 1
  • 39
  • 51
geronimo
  • 57
  • 4
  • Can you try to set the directions explicitly on your @Relationship annotations? – Michael Hunger Mar 27 '16 at 00:58
  • And can you try to leave off the NodeWithScore property in your class and see if the same issue happens. Might be that it gets mapped to the wrong fiel due to the same class? Can you also check your graph what that looks like. – Michael Hunger Mar 27 '16 at 00:59
  • Setting directions explicitly doesn't help. And yes, sorry for that, I forgot to mention it in my post - when I remove nodeWithScore from Node all works perfectly. Actually - it still works good if no setNodeWithScore() method is called. – geronimo Mar 27 '16 at 07:54
  • The graph created after session.save() is equal to: create (A:Node), (B:Node), (C:Node:NodeWithScore), (A)-[:CHILD]->(B), (B)-[:CHILD]->(C), (A)-[:SCORE]->(C), (B)-[:SCORE]->(C), (C)-[:SCORE]->(C) – geronimo Mar 27 '16 at 07:57
  • My guess is that NodeWithScore is also a Node and the mappings are too ambiguous. Will have to spend some time debugging this one – Luanne Mar 28 '16 at 09:09
  • Thanks Luanne. Small extra observation - if nodeWithScore is declared as Optional (or Set, or wrapped in any other way) - all works perfectly. – geronimo Mar 29 '16 at 17:26
  • My bad - Set works. Optional doesn't save the graph correctly. – geronimo Mar 29 '16 at 17:47

0 Answers0