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

用例是这样的:

现在有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生命周期的细节泄漏到应用层了。

不知大家有没有什么好的办法解决这个问题。

你可能感兴趣的:(DAO,Hibernate,jpa,领域模型)