浏览 4721 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-10-29
现在有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生命周期的细节泄漏到应用层了。 不知大家有没有什么好的办法解决这个问题。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-10-29
补充一下,以下是 A.removeB()的实现逻辑
public void removeB(B b) { getChildren().remove(b); // 在A属性的保存B的列表中把B清掉 b.setParent(null); // 由于B是主动控制方,需要在这里显示把B中的A引用设置为null } 以下是在B当中的Hibernate设置 @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "A_FK" ,nullable=true) public A getParent() { return parent; } 以下是A当中的Hibernate设置: @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) public List<B> getChildren() { return children; } |
|
返回顶楼 | |
发表时间:2008-10-29
cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null 这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。 |
|
返回顶楼 | |
发表时间:2008-10-29
Quake Wang 写道 cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null 这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。 请问orphan是什么意思呢?我使用的是J2EE的Persistent API,CascadeType并没有ORPHAN |
|
返回顶楼 | |
发表时间:2008-10-29
delete-orphan是Hibernate对JPA的扩展,你可以直接使用
http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/annotations/CascadeType.html |
|
返回顶楼 | |
发表时间:2008-10-29
可以了,谢谢
|
|
返回顶楼 | |
发表时间:2008-10-29
Quake Wang 写道 cascade 设置 all-delete-orphan
A的remove方法里面,将B从集合移除,同时将其parent设null 这样在session生命周期结束的时候,将会自动进行级联删除,你不需要调用dao的任何方法。 貌似用级联删除的时候,hibernate是一条条的删除,这点感觉不爽 |
|
返回顶楼 | |