如何在Spring Data Neo4j中实现双向关系?

时间:2015-01-28 14:31:29

标签: java neo4j spring-data relationship bidirectional

我正在使用Spring Data Neo4j建模一个非常简单的用例:我希望拥有通过友谊关系连接的人员。这是我的代码(这里省略了getter和setter):

@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);
    }

最终,我使用以下方法来使用我的人员:

@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);
}

根据我的理解,友谊关系应该是双向的,这就是我将其方向设置为(direction = Direction.BOTH)的原因。现在,当执行populateTwoPersons()方法时,它会导致创建两个人节点,但不会在它们之间的边缘中创建。

我尝试过的想法正在改变befriend() - 函数

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

或将关系的方向设置为direction = Direction.OUTGOING。然而,这会产生有向边,这不是我想要的。

为什么我不能在第一种情况下获得优势呢?有任何想法吗? :)

提前致谢, 马努

2 个答案:

答案 0 :(得分:2)

所有Neo4j边缘必须是定向的,它们不能是双向的。您可以单向创建友谊并在没有方向的情况下查询它。或者您可以在两个朋友之间创建两个单独的边。我认为后者更灵活,因为一个人可能认为另一个人是朋友但反之亦然。

答案 1 :(得分:1)

如果你不关心方向,那么你可以指定direction=Relationship.UNDIRECTED,这将保证两个节点实体之间的路径可以从任何一方导航。

例如,考虑两家公司之间的PARTNER_OF关系,其中

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

关系的方向无关紧要;只有这两家公司之间存在PARTNER_OF关系的事实才是重要的。因此,UNDIRECTED关系是正确的选择,确保两个合作伙伴之间只有这种类型的关系,并且可以从任一实体在它们之间进行导航。

资料来源:良好关系:The Spring Data Neo4j Guide Book