Spring,JPA - 双向@OneToMany:用另一个替换子列表

kie*_*tos 6 spring jpa spring-boot

我阅读了很多这方面的主题并进行了数百次实验,但到目前为止还没有成功。我有以下课程:

class Parent {
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL/*, orphanRemoval=true*/)
    private List<Child> children = new ArrayList<>();

class Child {
    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "parentId", nullable = false)
    @JsonIgnore
    Parent parent;
}
Run Code Online (Sandbox Code Playgroud)

我所做的就是尝试将children列表替换为 PATCH 请求中提供的列表:

    Hibernate.initialize(fromDb.getChildren());
    entityManager.detach(fromDb); // detach from JPA. I need this

    List<Child> newChildren = fromClient.getChildren();

    fromDb.getChildren().clear(); // get rid of all old elements

    for (Child child : newChildren) { // add the new ones
        child.setParent(fromDb);
        fromDb.getChildren().add(child);
    }

    ParentRepository.save(merged);
Run Code Online (Sandbox Code Playgroud)

行为如下:

  • 当我按原样运行它时,它会添加新的,但留下旧的!所以我不想要的孩子越来越多(抱歉..)
  • 当我取消注释orphanRemoval=true部分时...父级被删除

你能解释一下为什么它会这样吗?我在这里能做什么?

kie*_*tos 7

找到解决方案。

我应该有 orphanRemoval=true:

@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval=true)
Run Code Online (Sandbox Code Playgroud)

现在,由于 @ManyToOne 中的其他级联,它删除了父级。我将其更改为以下内容:

@ManyToOne(cascade = {CascadeType.MERGE})

现在可以了。