删除与Spring Data Neo4j的关系

时间:2017-03-09 13:42:38

标签: java spring entity relationship spring-data-neo4j

我使用SDN 4(v4.2.1),Spring启动(1.5.2),Neo4j(v3.1.0),我无法删除与save()方法的简单关系。

@NodeEntity
public class A extends MyModel {

    @Relationship(type="link")
    private B b;

    //Getters and setters
}

@NodeEntity
public class B extends MyModel {

    @Relationship(type="link", direction=Relationship.INCOMING)
    private List<A> as;

    //Getters and setters
}

public interface ARepository implements GraphRepository<A> {

}

public interface BRepository implements GraphRepository<B> {

}

//Create relationship
A a a = ...;
B b = ...;
a.setB(b);
a = aRepository.save(a); // works
//Delete relationship
a.setB(null);
aRepository.save(a); // Not works

如何成功删除A和B中的关系?

修改

谢谢你的回答。

自验证表格以来如​​何做到这一点。

@PostMapping(FORM)
public String form(@Valid @ModelAttribute("object") A a, BindingResult result, Model model, RedirectAttributes att, HttpServletRequest request) {
    log.info("/form");
    if (result.hasErrors()) {
        return form(model, a, request);
    }
    try {
        // a.getB() is null and a.getId() isn't null
        a = aService.save(a); // a.getB() isn't delete
        if (a.getId() == null)
            att.addFlashAttribute(MSG, a.getName() + " : create !");
        else
            att.addFlashAttribute(MSG, a.getName() + " : modify !");
    } catch (Exception e) {
        model.addAttribute(MSG, e.getMessage());
        log.error(e.getMessage(), e);
        return form(model, a, request);
    }
    return redirect(LISTE);
}

在这里,我的对象不在会话中,但是id由spring mvc填充。 并且通过下拉列表选择了b。

1 个答案:

答案 0 :(得分:2)

您在上面定义的代码与项目不同:

@Transactional
public void test() {
    A a = new A();
    a.setName("a1");
    B b = new B();
    b.setName("b1");
    a.setB(b);
    System.out.println(a);
    System.out.println("id : "+a.getId());
    A a2 = aRepo.save(a);
    System.out.println(a2);
    Long id = a2.getId();
    System.out.println("id : "+id);

    A a3 = new A();
    a3.setId(id);
    a3.setName("a2");
    System.out.println(a3);
    aRepo.save(a3);
    System.out.println(aRepo.findOne(id)); // b must be null
}

这里有很多事情要发生,所以我们先试着把它分解出来。

  1. 在变量A中创建了一个与B相关联的新a
  2. 然后将
  3. a保存到数据库,并将a的副本作为a2返回。在此阶段,aa2都将设置相同的内部图表ID(a.id == a2.id
  4. 创建了一个名为a3的新对象。上一步中的内部图表ID在a3(又名@GraphId)上设置,并且保存到数据库中,没有B引用。
  5. 从与A具有相同id的数据库中检索a2
  6. 让我们一起来看看每一步的幕后情况。

    1. 尚未与OGM / SDN互动。
    2. 此时a及其B引用将保存到数据库中。 OGM / SDN中的缓存现在保留a,其中包含指向b的链接以及分配了内部Neo4j ID的数据库(保存在每个对象的id字段中)。 a的参考副本已分配给a2
    3. 此时没有与OGM / SDN的互动。在调用save()之前,OGM不会管理此新对象。在这一点上,事情变得不确定。通过尝试在对象上设置内部ID,OGM会丢弃它,因为它不是“附加”,而是使用Session中的缓存值。
    4. 重要的是要注意,永远不应该真正改变@GraphId的值。事实上,它真的不应该被设计明智,因为它不是一个可变的属性。

      要解决您的问题,只需从会话中使用检索到的值,而不是实例化新对象并尝试将状态与之前的调用相关联。