JpaRepository删除子元素

4

我正在尝试进行一个非常简单的删除操作,但自从我将DAO更新为JpaRepository后,它就不起作用了。基本上是这样的:

A a = aRepository.findOne(id);
a.setSomeField("someNewString");

List<B> bList = a.getBs();
bList.clear();
aRepository.saveAndFlush(a);

这个字段被更新了,但是bList保持不变。我甚至尝试了:

A a = aRepository.findOne(id);
a.setSomeField("someNewString");

List<B> bList = a.getBs();
for(B b : bList) {
   bRepository.delete(b);
}
bRepository.flush();
bList.clear();
aRepository.saveAndFlush(a);

仍然是相同的...

A类看起来像这样:

@Entity
@Table(name = "A")
public class A implements Serializable {
    private static final long serialVersionUID = -1286451120913657028L;

    @Column(name = "id", length = 16, nullable = false, updatable = false)
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    @Basic(fetch = FetchType.EAGER)
    @Id
    protected UUID id;

    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER)
    @Cascade({ CascadeType.ALL })
    List<B> bList;

    // getter + setter
}

我在哪里出了问题?!


B班级:

@Entity
@Table(name = "B")
public class B implements Serializable {
    @Column(name = "id", length = 16, nullable = false, updatable = false)
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @GeneratedValue(generator = "uuid")
    @Basic(fetch = FetchType.EAGER)
    @Id
    protected UUID id;

    @ManyToOne(optional = false)
    @JoinColumns({ @JoinColumn(name = "A_id", referencedColumnName = "id", nullable = false) })
    @Valid
    A a;

    // setter + getter
}

设置器(setter)和取值器(getter)都应该尽可能简单:

public List<B> getBList() {
    return bList;
}

public void setBList(List<B> bList) {
    this.bList = bList;
}

更多信息:

  • Spring 3.2.2
  • Hibernate 4.2.2
  • Spring-Data-Commons 1.5.1
  • Spring-Data-JPA 1.3.2

B类是什么样子的?A.getBs()方法呢? - Spiff
更新了初始帖子。 - Benjamin M
1个回答

12

A.bList属性更新如下:

public class A {
    @OneToMany(mappedBy = "a", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    List<B> bList;
}
< p > orphanRemoval = true 注释属性将告诉底层的 JPA 实现删除没有任何父项的 B 记录。

另外,由于 B 端管理关联,所以在解除关系时应该清除其 a 属性。为了使代码更易读,并从调用者身上卸下实现细节的负担,你应该在 A 中引入管理方法:

public class A {
    public void clearBList() {
        for (B b : bList) {
            b.releaseA();
        }
        bList.clear();
    }
}

public class B {
    void releaseA() {
        this.a = null;
    }
}

为防止A类不知情的情况下客户端直接修改集合,请避免直接暴露集合,而是返回一个不可变版本。 A 管理着 B 列表,因此应该对其具有完全控制权!

public class A {
    public List<B> getBList() {
        return Collections.unmodifiableList(bList);
    }
}

希望这能帮到你。


谢谢,我现在已经把它搞定了:我把CascadeType.ALL放在了@OneToMany注释里。以前我必须使用Hibernate的@Cascade注释。现在我会保留两个注释。我还添加了orphanRemoval = true。清除列表a.getBList().clear(); aRepository.saveAndFlush(a);就足够了。 :) - Benjamin M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接