Search code examples
javaneo4jspring-datarelationshipbidirectional

How to implement a bidirectional relationship in Spring Data Neo4j?


I am modelling a very simple use case, using Spring Data Neo4j: I want to have Persons, which are connected by friendship relations. Here is my code (getters and setters are omitted here):

@NodeEntity
public class Person {
    @GraphId
    private Long id;
    private String name;
    private String password;

    @RelatedTo(type = "FRIEND_OF", direction = Direction.BOTH)
    private Set<Person> friends = new HashSet<Person>();

    public Person() {};

    public Person(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public void befriend(Person person) {
        this.friends.add(person);
    }

Ultimately, I make use of the following method in order to make use of my Persons:

@Transactional
private void populateTwoPersons() {
    Person person1 = new Person("Alice", "pw1");
    Person person2 = new Person("Bob", "pw2");

    List<Person> persons = Arrays.asList(person1, person2);
    personRepository.save(persons);

    person1.befriend(person2);

    personRepository.save(persons);
}

In my understanding a friendship relation should be bidirectional, that is why I set its direction to (direction = Direction.BOTH). Now when executing the populateTwoPersons() method it results in the creation of the two person nodes, but not in an edge between them.

Ideas that I have tried are altering the befriend()-function to

public void befriend(Person person) {
    this.friends.add(person);
    person.getFriends().add(this);
}

or setting the direction of the relationship to direction = Direction.OUTGOING. This however creates a directed edge, which is not what I want.

Why don't I get an edge in the first case altogether? Any ideas? :)

Thanks in advance, Manu


Solution

  • All Neo4j edges must be directed and they cannot be bi-directional. You can either create the friendship one-way and query it without direction. Or you can create two separate edges between the two friends. I think the latter is more flexible as one person may consider the other a friend but not vice versa.