关于关联对象的级联删除的问题。(应用于“充血模型”)

本文探讨了在使用Hibernate框架时如何有效地通过聚合根管理对象之间的关系。具体讨论了当需要从聚合根对象A中移除B对象时,如何实现B对象的级联删除。面对直接调用A.removeB(B)无法实现B的级联删除的问题,文章提出了可能的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用例是这样的:

现在有A、B两个对象,彼此关系是 A 1 : n B

换言之,A之中就有一个集合引用了B,现在我想通过调用 A.removeB(B b)方法,Hibernate就能透明的把B从数据库中删除掉,这样做的好处主要在于在“充血模型”中,领域对象有聚合根,所有对领域对象的操作必须由聚合根发起,上面的例子中,A是B的聚合根,因此需要删除B,则必须通过A发起。应用层的代码如下:


 
public class SomeService {
public removeBFromA(Long bId,Long aId) {
B b = bDao.get(bId);
A a = aDao.get(aId);
a.removeB(b);
}


我通过Hibernate设置了A、B的一对多关系,通过“mappedby”设置了B为主动方(主要是考虑插入数据的时候,不需要对B的外键调用多一次Update语句),casdaceType是ALL,但我发现,当删除A的时候,确实可以级联删除B,但当调用A.remove(B)的时候,只能把B的外键清空,并没有把B删除掉,而如果我尝试把B的外键的nullable设置为false,在调用b.setA(null)的时候,还会出现数据完整性异常,所以,根本无法通过A来发起对B的删除操作。(除非把B的DAO放置到A中,由A.removeB()方法显式调用DAO的方法删除B,但这就把持久化逻辑加入到领域对象中了,而持久化逻辑应该完全由应用层Servcie完成)。

于是,最终不得不把上面的代码改为:


 
public class SomeService {
public removeBFromA(Long bId,Long aId) {
B b = bDao.get(bId);
A a = aDao.get(aId);
a.removeB(b);
bDao.remove(b); // 领域层的客户代码必须显式的删除B
}


上面的代码表面上没问题,但事实上,应用层必须显式的去删除B,这样做就不太优雅了,因为领域层把A管理B生命周期的细节泄漏到应用层了。

不知大家有没有什么好的办法解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值