【问题标题】:How to delete bidirectional many-to-many association如何删除双向多对多关联
【发布时间】: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 关联中连接表的“隐含性质”。

标签: hibernate many-to-many


【解决方案1】:

我看不出代码有什么不优雅的地方。它在所有情况下都可以正常工作,并且不会做任何不应该做的额外事情。当我说A拥有方是关系AB时,这意味着创建或删除关系掌握在A手中。B在关系中没有发言权。因此,如果我想将 B 移到其他地方,则 A 必须先放开 B,然后才能将 B 移走。因此,在选择拥有方时,您应该考虑您将如何处理这些对象。

【讨论】:

  • 感谢您的回答。我只是想听听。我是 Hibernate 技术的初学者,我不是 100% 确定我对问题的理解,但现在没问题。当我提到优雅时,我认为可能有针对此类问题的一行代码解决方案,因为连接表在某种意义上是隐含的工件,即我没有可能从联合表本身显式删除行.但是关于所有者的解释可以澄清事情。
猜你喜欢
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
相关资源
最近更新 更多