如何使用spring-data-neo4j删除多对多关系?

时间:2017-02-07 02:42:18

标签: spring-data-neo4j spring-data-neo4j-4

我有以下实体:

@NodeEntity(label = "A")
public class A {
    @Property(name = "something")
    private String someProperty;

    //... getters and setters
}

@NodeEntity(label = "B")
public class B {
    @Property(name = "someOtherThing")
    private String otherProperty;

    //... getters and setters
}

@RelationshipEntity(type = "AB")
public class AB {
    @StartNode
    private A start;

    @EndNode
    private B end;

    @Property(name = "evenOtherThing")
    private String prop;

    //... getters and setters
}

所以,在这种情况下,我有(:A)-[:AB]->(:B)。我可以有几个AB s(意思是我可以多次连接A到B,每次都有不同的属性)。

使用该配置,我可以毫无问题地保存AB实例,但是当只删除关系时,我找不到使用spring-data-neo4j方法的方法。

我尝试的事情:

1-自定义查询:

@Repository
public interface ABRepository extends GraphRepository<AB> {

    @Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} DELETE ab")
    void deleteBySomething(@Param("something") String something);
}

用法:

@Autowired
ABRepository repository;

//...
repository.deleteBySomething(something);

它没有按预期工作。 A节点与AB关系一起被删除。如果我直接在数据库中运行查询,它将按预期工作。

2-从存储库中删除:

@Repository
public interface ABRepository extends GraphRepository<AB> {

    @Query("MATCH (a:A)-[ab:AB]->(b:B) WHERE a.something={something} RETURN a,ab,b")
    Iterable<AB> findBySomething(@Param("something") String something);
}

用法:

Iterable<AB> it = repository.findBySomething(something);
repository.delete(it);

同样的东西。节点被删除。我试图迭代Iterable<AB>并逐个删除关系,但也没有成功。

3-在AB内部取消A和B的引用并保存AB:

存储库的相同代码,具有不同的用法:

Iterable<AB> it = repository.findBySomething(something);
for (AB ab : it) {
    ab.setA(null);
    ab.setB(null);
}
repository.save(it);

这里我只是尝试随机的东西。它没有按预期工作。该框架引发了一个异常,表明起始节点和结束节点不能为空。

那么,我做错了什么?如何在不删除链接节点的情况下使用spring-data-neo4j从数据库中删除简单关系?

记录:我的neo4j数据库是v.3.0.4,我的spring-data-neo4j是v.4.1.4.RELEASE。运行Java 8。

1 个答案:

答案 0 :(得分:2)

最后问题是两个因素的总和。

首先:问题中没有提到,但我保存AB实体的方式并不理想。我直接使用repository.save(ab),这可以使框架对内部的A和B实体做一些魔术。为了保存关系而不触及相关实体,应该使用repository.save(ab, 0)

第二:使用自定义查询删除实体比获取实体然后删除它们更直观,因此使用该方法是我的第一个目标。在这里,我再次对幕后的一些魔法感到困惑,在这个问题上有更好的描述:Spring Data Neo4j 4returning cached results?

总之,在使用自定义查询删除实体或关系后,我应该清除会话:

@Autowired
Session session;

//...
repository.deleteBySomething(something);
session.clear();

这两个调整修复了我对框架的奇怪行为。