问题:
我 在* 两个实体 A和B 之间 有 多对多关联 。我将 A实体 设置为其 关系 的 所有者 (inverse = true在b.hbm.xml中A的集合上)。 *
当我 删除一个A实体时 , 联接表中的 相应 记录也会被删除 。 当我 删除一个B实体时 , 联接表中的 相应 记录不会被删除 (完整性违反异常)。
-
让我们考虑一些非常简单的 示例 :
class A{ Set<B> bset=new HashSet<B>(); //... } class B{ Set<A> aset=new HashSet<A>(); //... }
文件 a.hbm.xml [仅适用于m-to-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的关系。但是,另一方面,这不是逻辑的,或者至少不是我必须明确指出的不是orm的解决方案删除出现具体B实体的连接表中的所有记录,然后删除B实体,如我在情况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)?
我看不出代码有什么不好的地方。它在所有情况下都能正常工作,并且不会做任何不应该做的事情。当我说A拥有一方是关系AB时,这意味着创建或删除该关系由A掌握。B在该关系中没有发言权。因此,如果我想将B移动到其他地方,则A必须先放开B,然后才能将B移开。因此,在选择拥有方时,应考虑将要使用的对象。