首页 > 解决方案 > 在两个节点上指定关系会导致 Spring Data Neo4j 中的逻辑循环映射依赖关系

问题描述

我有一个用例,我需要在两个节点类中指定关系,一个作为传入,一个作为传出。这在 SDN 6.0.2 中有效,但在尝试更新到 6.1.5 时失败。我有一个基类和两个自定义类定义为

abstract class Base(
    @DateLong @CreatedDate @LastModifiedDate var updated: Date? = null,
    @CreatedBy @LastModifiedBy var source: String? = null,
) {
    abstract val customId: String
}

@Node
data class Foo(
    @Id override val customId: String,
    val name: String,
    @Relationship(
        type = "CONFIGURED_TO",
        direction = Relationship.Direction.INCOMING
    ) var bars: Set<Bar> = emptySet(),
) : Base()

@Node
data class Bar(
    @Id override val customId: String,
    val name: String,
    @Relationship(
        type = "CONFIGURED_TO",
        direction = Relationship.Direction.OUTGOING
    ) var foos: Set<Foo> = emptySet(),

) : Base()

当使用最近的 SDN 更新执行查询时,两个节点类中定义的这种关系会导致org.springframework.data.mapping.MappingException: The node with id 10 has a logical cyclic mapping dependency. Its creation caused the creation of another node that has a reference to this.

获取时我不需要获取Foo节点Bar,但是在更新关系时定义关系对于更简单的实现都是必需的。有没有办法在使用 Spring Data Neo4j 派生查询时不获取节点?

标签: spring-bootkotlinspring-data-neo4j

解决方案


一些背景:事实是它在 6.0(.2) 中也不能 100% 正确工作。Foo如果或Bar解决构造函数依赖关系(由数据类定义)的循环,SDN 不仅创建了一个实例,而且创建了两个实例。当然,这种行为不是故意的。

要在获取Foo时不获取节点,Bar您应该使用投影:https ://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#projections

例如(在 Java 中)

interface BarProjection {
   String getName();
}

并在存储库中

interface BarRepository extends Neo4jRepository<Bar, String> {
   BarProjection findByName(String name);
}

但这不会使您免于清理导致数据类中的鸡/蛋问题的循环定义的依赖项。


推荐阅读