3

假设您有一个从 A 类到 B 类的单向一对多关联,如下所示:

public class A {
    @OneToMany(cascade = CascadeType.ALL)
    private List<B> myBs;
}

public class B {
    //I know nothing about A
}

在数据库中,这些通过第三个表连接,保留它们的 ID。

现在,我想删除一个连接到 A 的 B 对象。A 有自己的存储库类,B 有自己的存储库类。

在我的项目中以类似设置完成此操作的方式是首先要求有问题的 A 删除有问题的 B,然后告诉EnitityManager从数据库中删除 B。

这让我有点卡在两个选择之间,在我看来它们都不是最佳选择:

  1. 中的存储库方法BRepository处理从其连接的 A 中删除 B 以及通过EntityManager. 我不喜欢这样,因为 B 的存储库类将不得不操作 A 对象。

  2. BRepository 中的存储库方法仅处理通过 EntityManager 进行的删除,由调用者将其从 A 的集合中删除。我更不喜欢这个,因为如果有人在没有先从 A 的集合中删除 B 的情况下调用存储库,它将严重失败。

在这两个中,我发现第一个是迄今为止最好的。但是,我真的不认为它是干净的。

Hibernate 中是否有一些构造允许在从数据库中删除时从它所属的任何集合中删除要删除的项目?(试图只删除 B 失败,因为包含它的 A 也加载到同一个事务中,所以它在事务结束时失败,当它试图存储被删除的东西时。)

(在 A 中添加会mappedBy解决@OneToMany-mapping问题吗?)

4

3 回答 3

3

通过使用孤儿删除,我找到了解决此问题的方法。

通过将 A 中的映射更改为:

public class A {
   @OneToMany(cascade = CascadeType.ALL)
   @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
   private List<B> myBs;
}

我只能说

a.getMyBs().remove(b);

并在持久化后被b删除。a

于 2012-09-11T14:34:39.110 回答
2

跳出 Hibernate 思维模式,问问自己:谁拥有Bs?

业主最终要对他们的财产负责。通常,当 a 不能没有 a 并且每个都由一个完全拥有时,这BA正确BA

所以如果As拥有Bs,ARepository则负责清理Bs。我会创建一个方法来ARepository进行清理并在BRepository.

于 2012-09-11T13:34:55.583 回答
0

如果您确实希望将存储库分开,则另一个选项是在顶部创建一个服务类,该服务类知道两者,并将以与您的选项 1 方法类似的方式为您处理删除。

(在 A 中的 @OneToMany-mapping 上添加 mappedBy 会解决问题吗?)

我认为这取决于他的存储库实现。对于 JPA EntityManager,如果会话关闭,A 将在您删除 B 时分离,即使它是双向映射也是如此。

于 2012-09-11T13:41:53.427 回答