【发布时间】:2011-04-27 21:15:06
【问题描述】:
问题:
我在两个实体 A 和 B 之间有多对多关联。 我将 A entity 设置为 owner of 他们的relationship(inverse=true 位于 A 在 b.hbm.xml 中的集合上)。
当我删除一个A实体时,连接表中对应的记录被删除。
当我删除一个B实体时,对应的连接表中的记录不会被删除(完整性违规异常)。
--
让我们考虑一些非常简单的示例:
class A{
Set<B> bset=new HashSet<B>();
//...
}
class B{
Set<A> aset=new HashSet<A>();
//...
}
文件 a.hbm.xml [仅限 m 到 m 映射]:
<set name="bset" table="AB">
<key name="a_id"/>
<many-to-many column="b_id" class="B"/>
</set>
文件 b.hbm.xml [仅限 m-to-m 映射]:
<set name="aset" table="AB" inverse="true">
<key name="b_id"/>
<many-to-many column="a_id" class="A"/>
</set>
数据库关系:
A(id,...)
B(id,...)
AB(a_id,b_id)
假设我们有AB 联合表中有一些记录。例如:
AB = {(1,1),(1,2)}
其中 AB= { (a_id , b_id) | ... ... }
--
情况 1 - 可能是因为 A 是 AB 关系的所有者:
A a=aDao.read(1); //read A entity with id=1
aDao.delete(a); //delete 'a' entity and both relations with B-entities
情况 2 - 不起作用:
B b=bDao.read(1); //read B entity with id=1
bDao.delete(b); //foreign key integrity violation
一方面,这在某种程度上对我来说是合乎逻辑的,因为 A 实体负责他与 B 的关系。 但是,另一方面,我必须明确删除出现具体 B 实体的连接表中的所有记录,然后删除 B 实体,这不合逻辑或至少不是类似 orm 的解决方案,如我在情况3:
情况 3 - 有效,但不是“优雅”:
B b=bDao.read(1);
Set<A> aset=b.getA(); //get set with A entities
Iterator i=aset.iterator();
//while removes 'b' from all related A entities
//while breaks relationships on A-side of relation (A is owner)
while(i.hasNext()){
A a=i.next();
a.bset.remove(b); //remove entity 'b' from related 'a' entity
aDao.update(a); //key point!!! this line breaks relation in database
}
bDao.delete(b); //'b' is deleted because there is no related A-entities
--
所以,我的问题:有没有更方便的方法来删除双向多对多关联中的无所有者实体(在我的示例中为 B)以及他的所有多对多来自联合表的关系?
【问题讨论】:
-
@Don Roby - 我认为建议的主题很相似,但我找不到我的问题的答案。在那里,作者想明确删除关联。另一方面,当我删除一些形成关联的实体时,我想隐式删除关联。我采用这种方法的原因是 m-to-m 关联中连接表的“隐含性质”。