hibernate - 如何删除双向多对多关联

标签 hibernate many-to-many

问题:

我在两个实体 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 移走。因此,在选择所有者时,您应该考虑将如何处理这些对象。

关于hibernate - 如何删除双向多对多关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5810689/

相关文章:

mysql - 关于 MySQL 和多对多填充关联实体的建议

java - 如何让 Hibernate/Spring/JPA 自动更新新实体的 ID

java - 状态模式 : States as Hibernate singleton entities

java - Hibernate 多对多结果不符合预期 - 仅获取最后一条记录

ruby-on-rails - Ruby on Rails 'has_many :through' ,存储数据

entity-framework - 如何使用 Entity Framework 为多对多关系表添加条目

java - 具有一对多和多对多关系的 JOOQ pojos

mysql - JSON 数据不包含实体

javax.persistence.EntityExistsException 与 SequenceGenerator

java - 二级缓存 : Spring 3. 2.2 + Hibernate 4.2.0 Infinispan