Spring Data JPA - ManyToOne无法在不修改父列表的情况下删除子节点

时间:2017-08-18 09:39:07

标签: spring hibernate jpa spring-data-jpa many-to-one

我因为以下问题而奋斗了一周:

如何通过存储库删除子实体而不修改关系拥有(父)一侧的List?

提前致谢。

我希望得到一些答案!

孩子类:

@Entity
@Table(name = "child")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Child implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @ManyToOne
    private Parent parent;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

父级类:

@Entity
@Table(name = "parent")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Parent implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    private Set<Child> children = new HashSet<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Set<Child> getChildren() {
        return children;
    }

    public void setChildren(Set<Child> children) {
         this.children = children;
    }

    public Parent addChild(Child child) {
        this.children.add(child);
        child.setParent(this);
        return this;
    }

    public Parent removeChild(Child child) {
        this.children.remove(child);
        child.setParent(null);
        return this;
    }
}

此处测试

@Test
@Transactional
public void testParentToChildRelationShip() {
    Parent parent = new Parent();
    Child child = new Child();

    parent.addChild(child);
    parent.addChild(new Child());
    parent.addChild(new Child());
    parent.addChild(new Child());

    parentRepository.save(parent);

    Assertions.assertThat(parentRepository.count()).isEqualTo(1L);
    Assertions.assertThat(childRepository.count()).isEqualTo(4L);

    childRepository.delete(child);


    Assertions.assertThat(parentRepository.count()).isEqualTo(1L);
    // fails
    Assertions.assertThat(childRepository.count()).isEqualTo(3L);

    parentRepository.delete(parent.getId());

    Assertions.assertThat(parentRepository.count()).isEqualTo(0L);
    Assertions.assertThat(childRepository.count()).isEqualTo(0L);
}

如果我在删除孩子之前插入,测试将起作用,

child.getParent().removeChild(child);

但我想避免这样称呼。 有没有办法让它只调用Child-JPA-Repository.delete方法?或者我错过的其他注释?

2 个答案:

答案 0 :(得分:1)

由于childparent有关联,因此您需要使用

删除子级和父级之间的链接
parent.removeChild(child);

child.getParent().removeChild(child);

答案 1 :(得分:0)

从父类以及children

的setter和getter中删除这些行
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
        @JsonIgnore
        @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
        private Set<Child> children = new HashSet<>();

我认为您可以从child mapping中移除parent class,以便您可以使用ChildRepository delete()方法轻松删除子行,但问题是您必须保存您的孩子manually使用ChildRepository save()。您无法使用ParentRepository使用父对象保存子对象。更改测试代码,如下所示,以保存childparent

Parent parent = new Parent();
Parent parent = parentRepository.save(parent);

    Child child = new Child();
    child.setParent(parent);
    childRepository.save(child);