> 文章列表 > springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

背景

依赖

springboot版本 2.7.10
本地neo4j安装的版本:4.4.19

依赖如下:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-neo4j</artifactId></dependency>

springboot整合neo4j官网地址:Accessing Data with Neo4j

遇到的问题:

按照官网向导本地运行后,得不到正确的关系

neo4j得到的数据如下:
springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

            greg = personRepository.findByName(greg.getName());greg.worksWith(roy);greg.worksWith(craig);personRepository.save(greg);roy = personRepository.findByName(roy.getName());roy.worksWith(craig);// We already know that roy works with gregpersonRepository.save(roy);log.info("Lookup each person by name...");team.stream().forEach(person -> log.info("\\t" + personRepository.findByName(person.getName()).toString()));

上面代码设置了greg的同事是roy,但是查询roy的同事确无法得到greg。
springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

问题原因分析过程

参考资料1:

首先从官方github找相关issue,有人遇到同类问题,并得到回复如下(问题连接地址:https://stackoverflow.com/questions/68472313/spring-data-neo4j-6-relationship-undirected)。
springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

也就是说在早期版本,我们可以在关系这里设置UNDIRECTED属性,实现数据间的双向关系。但是后来出于特别的考虑,Neo4j中的关系都是带有方向的关系,不再支持UNDIRECTORY这个属性(Neo4j-OGM支持?)

参考资料2:

官方示例代码在Person实体中也写了注释,大意和上述一致,而且给了连接(https://dzone.com/articles/modelling-data-neo4j)

   /* Neo4j doesn't REALLY have bi-directional relationships. It just means when querying* to ignore the direction of the relationship.* https://dzone.com/articles/modelling-data-neo4j*/@Relationship(type = "TEAMMATES",direction = Relationship.Direction.INCOMING)public Set<Person> teammates;

在这个连接中主要介绍了directed relationships 和 bidirectional relationships之间的区别及具体使用场景。

得到的核心信息如下:
springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

这里引入了Cypher语法,也就是通过这些语法能够在neo4J中进行增删改查。通过模仿+实践得到结果如下:

MATCH (p1:Person)-[r:TEAMMATES]-(p2:Person) where p1.name = 'Roy' RETURN p2

springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

此图结果表明,通过 - 查询是忽略关系方向的,能够得到roy的同事有Greg

MATCH (p1:Person)<-[r:TEAMMATES]-(p2:Person) where p1.name = 'Roy' RETURN p2

springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

此图结果表明,通过 -> 查询是带有关系方向的,得不到roy的同事有Greg

解决办法

自定义查询语句,使用-查询忽略方向即可,修改如下

  @Query("MATCH (p1:Person)-[r:TEAMMATES]-(p2:Person) where p1.name = $name RETURN p2")List<Person> findByTeammatesName(String name);

按照官网demo的打印依然无法得到预期结果,因为数据库中虽然支持查询双向关系,但是并不能自动关联到java的Person对象的teammates中,所以我这里手动查询关系,再把关系设置到java实体中并打印即可。
在AccessingDataNeo4jApplication中修改如下

         log.info("-------------Lookup each person by name from neo4j...");team.forEach(p -> {List<Person> teammatesName = personRepository.findByTeammatesName(p.getName());p.setTeammates(new HashSet<>(teammatesName));log.info("\\t" + p.toString());});

验证

再次运行程序,得到正确结果:
springboot2.7.10整合neo4j -- 关系双向绑定(UNDIRECTED)

心理咨询网