如何删除双向多对多关联 [英] How to delete bidirectional many-to-many association

查看:123
本文介绍了如何删除双向多对多关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:



我有两个实体之间的多对多关联 A和乙即可。
我将实体作为 关系的所有者(inverse = true在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-to-m映射:

 < set name =bsettable = AB > 
< key name =a_id/>
< / set>

文件 b.hbm.xml [仅限m-to-m映射]:

 < set name =asettable =ABinverse =true> 
< key name =b_id/>
< / set>

数据库关系

  A(id,...)
B(id,...)
AB(a_id,b_id)

假设我们在AB联合表中有一些记录。例如:


AB = {(1,1),(1,2)}
blockquote>

其中AB = {(a_id,b_id)| ...}}



-



情况1 - 作品可能是因为A是AB关系的所有者:

  A a = aDao.read(1); //读取一个id = 1的实体
aDao.delete(a); //删除'a'实体以及与B实体的关系

状态2 - 不起作用:

  B b = bDao.read(1); //读取ID为1的b实体
bDao.delete(b); //外键完整性违规

一方面,这对我来说是合乎逻辑的,因为A实体负责他与B.
的关系但是,另一方面,它是不合逻辑的,或者至少它不是类似于orm的解决方案,我必须显式删除具体B实体出现的连接表中的所有记录,然后删除B实体,如我在情况3中所示:

情境3 - 有效,但它不是'优雅' :

  B b = bDao.read(1); 
Set< A> ASET = b.getA(); //用A实体设置
Iterator i = aset.iterator();

//同时从所有相关的A实体中删除'b'
//在关系的A面上断开关系(A是所有者)
while(i.hasNext( )){
A a = i.next();
a.bset.remove(b); //从相关的'a'实体中删除实体'b'
aDao.update(a); //关键!!!这一行破坏数据库中的关系
}
bDao.delete(b); //'b'被删除,因为没有相关的A实体

-



所以,我的问题:是否有更方便的方法来删除双向多对多关联中的无所有者实体(本例中为B)所有他从联合表中的多对多关系?

解决方案

我没有看到代码的优雅之处。它在任何情况下都可以正常工作,并且不会做任何不该做的事情。当我说A是拥有方是AB关系时,这意味着创建或删除关系在A的手中。B在关系中没有发言权。所以如果我想把B移到别的地方,A必须放开B才能将B移开。因此,在选择自己的一面时,你应该考虑你将如何处理这些对象。


Problem:

I have many-to-many association between two entities A and B. I set A entity as an owner of their relationship(inverse=true is on A's collection in b.hbm.xml).

When i delete an A entity, corresponding records in join table are deleted.
When i delete an B entity, corresponding records in join table are not deleted (integrity violation exception).

--

Let's consider some very simple example:

class A{  
    Set<B> bset=new HashSet<B>();
    //...
}  

class B{  
    Set<A> aset=new HashSet<A>();  
    //...
}

File a.hbm.xml [m-to-m mappings only]:

<set name="bset" table="AB">  
    <key name="a_id"/>  
    <many-to-many column="b_id" class="B"/>  
</set>

File b.hbm.xml [m-to-m mappings only]:

<set name="aset" table="AB" inverse="true">  
    <key name="b_id"/>  
    <many-to-many column="a_id" class="A"/>  
</set>

Database relations:

A(id,...)  
B(id,...)  
AB(a_id,b_id)

Suppose that we have some records in AB joint table. For example:

AB = {(1,1),(1,2)}

where AB= { (a_id , b_id) | ... ... }

--

Situation 1 - works probably because A is owner of AB relationship:

A a=aDao.read(1);  //read A entity with id=1  
aDao.delete(a);    //delete 'a' entity and both relations with B-entities

Situation 2 - doesn't work:

B b=bDao.read(1);   //read B entity with id=1  
bDao.delete(b);     //foreign key integrity violation

On the one hand, this is somehow logical to me, because the A entity is responsible for his relation with B. But, on the other hand, it is not logical or at least it is not orm-like solution that I have to explicitly delete all records in join table where concrete B entity appears, and then to delete the B entity, as I show in situation 3:

Situation 3 - works, but it is not 'elegant':

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

--

So, my question: is there any more convenient way to delete no-owner entity (B in my example) in bidirectional many-to-many association and all of his many-to-many relations from joint table?

解决方案

I do not see what is not elegant about the code. It works fine in all cases and does not do any extra stuff which it is not supposed to. When I say A is owning side is a relationship AB, this would imply that creating or deleting the relationship lies in the hands of A. B has no say in the relationship. So if I want to move B somewhere else, A has to let go of B before B can be moved away. Hence, when choosing the owning side you should consider what you are going to do with the objects.

这篇关于如何删除双向多对多关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆