使用spring-data-neo4j时,删除节点也会删除关系,这与cypher默认值不同

使用spring-data-neo4j时,删除节点也会删除关系,这与cypher默认值不同,neo4j,spring-data-neo4j,Neo4j,Spring Data Neo4j,我正在编写一个spring-data-neo4j应用程序,并在玩CRUD 在cypher中,如果我无法删除与另一个节点有关系的节点,则必须先删除该关系 在spring-data-neo4j中,这似乎没有相同的行为。当我删除一个节点时,它也会删除关联的关系 有没有办法从默认存储库中防止这种行为?如果删除了具有关系的节点,如何让spring数据抛出异常 这是我期望和渴望的行为: @NodeEntity class Junction { @GraphId Long id } @NodeEnt

我正在编写一个spring-data-neo4j应用程序,并在玩CRUD

在cypher中,如果我无法删除与另一个节点有关系的节点,则必须先删除该关系

在spring-data-neo4j中,这似乎没有相同的行为。当我删除一个节点时,它也会删除关联的关系

有没有办法从默认存储库中防止这种行为?如果删除了具有关系的节点,如何让spring数据抛出异常

这是我期望和渴望的行为:

@NodeEntity
class Junction {
    @GraphId Long id
}

@NodeEntity
class Route {
    @GraphId Long id
    @Fetch Junction from
    @Fetch Junction to
}

@Transactional
def "should not be able to delete a junction that is used"() {
    given: "a junction that is in use"
    Junction j = new Junction()
    Route r = new Route(from: j, to: new Junction())
    routeRepository.save(r)

    when: "the junction is removed"
    junctionRepository.delete(j)

    then:
    thrown SomeExceptionBecauseTheNodeHasAnAssociatedRelationship
}

我认为SDN存储库删除方法更类似于:

MATCH (j:Juntion)
OPTIONAL MATCH (j)-[r]-()
DELETE r, j
对我来说,这正是我想要的,但是如果您想要一种不同的行为,您可以在您的junctionRepository界面中覆盖delete方法,如下所示:

@Override
@Query("MATCH (j:Junction) WHERE ID(j)={0} DELETE j")
public void delete(Long id);

现在,如果您尝试删除具有关系的节点,您将在堆栈的某个位置获得ConstraintViolationException。这样做的缺点是,您必须记住为每个存储库执行此操作,为了鼓励您记住,您可以在自己的接口中引入一个deleteSafe习惯用法,并对每个存储库进行扩展,我想接口组合的缺点是您仍然无法强制任何接口实际实现新方法。

谢谢@JohnMark13;一个完美的答案。非常感谢。嗯,这似乎不起作用。如果我在@Query中引入语法错误,那么密码肯定正在运行,我会得到一个密码异常。但是,无论关系如何,仍将删除节点。我已经通过在调用delete之前和之后转储数据库来确认正在设置关系属性。这怎么可能?据我所知,它不可能,我刚刚在这里运行了一个测试,它肯定给出了一个异常-HeuristicCompletionException,带有嵌套的org.neo4j.graphdb.ConstraintViolationException:Node记录节点[15,used=false,rel=12,prop=-1,labels=Inline0x0:[],light]仍然有关系。你能用版本信息和SDN配置更新你的问题吗;它正在运行——但是grails中的集成测试框架有一些问题,我们阻止了测试正常工作。您的测试有问题吗?接头j和新接头在保存之前将是相同的空ID节点。当你调用deletej时,你以前保存过它并更新了j.id吗?没有,看起来没问题。当spring数据持久化连接时,它会被分配一个id。当然,但是你的代码是有风险的。当然,这只是一个测试。您能确认j在junctionRepository.deletej中有一个id,并且它等于r.from.id吗?是的,断言j.id&&j.id==r.from.id就可以通过了。问题似乎更深,我现在非常确定这与grails中的集成测试环境有关。如果我在生产代码grails run应用程序中运行相同的代码,则会引发异常。是的,问题似乎出在测试框架上,而不是Neo4j:。