简体   繁体   中英

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

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.

If you don't care about the direction then you can specify direction=Relationship.UNDIRECTED which will guarantee that the path between two node entities is navigable from either side.

For example, consider the PARTNER_OF relationship between two companies, where

(A)-[:PARTNER_OF]→(B) implies (B)-[:PARTNER_OF]→(A)

The direction of the relationship does not matter; only the fact that a PARTNER_OF relationship exists between these two companies is of importance. Hence an UNDIRECTED relationship is the correct choice, ensuring that there is only one relationship of this type between two partners and navigating between them from either entity is possible.

Source: Good Relationships: The Spring Data Neo4j Guide Book .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM