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).
我在两个实体A和B之间有多对多的关联。我将一个实体设置为它们关系的所有者(inverse = true在b.hbm.xml中的A集合上)。
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).
删除A实体时,删除连接表中的相应记录。当我删除B实体时,连接表中的相应记录不会被删除(完整性违规例外)。
--
-
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]:
文件a.hbm.xml [m-to-m映射]:
<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]:
文件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>
Database relations:
数据库关系:
A(id,...)
B(id,...)
AB(a_id,b_id)
Suppose that we have some records in AB joint table. For example:
假设我们在AB联合表中有一些记录。例如:
AB = {(1,1),(1,2)}
AB = {(1,1),(1,2)}
where AB= { (a_id , b_id) | ... ... }
其中AB = {(a_id,b_id)| ......}
--
-
Situation 1 - works probably because A is owner of AB relationship:
情况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
Situation 2 - doesn't work:
情况2 - 不起作用:
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:
一方面,这对我来说是合乎逻辑的,因为A实体负责他与B的关系。但是,另一方面,它不符合逻辑,或者至少它不是类似orm的解决方案,我必须明确删除连接表中出现具体B实体的所有记录,然后删除B实体,如我在情境3中所示:
Situation 3 - works, but it is not 'elegant':
情况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
--
-
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?
所以,我的问题:是否有更方便的方法来删除双向多对多关联中的无所有者实体(在我的例子中是B)以及他从联合表中获得的所有多对多关系?
1 个解决方案
#1
8
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.
我没有看到代码有什么不优雅。它在所有情况下都能正常工作,并且不会做任何不应该做的额外的事情。当我说A拥有的一方是AB的关系时,这意味着创建或删除关系掌握在A的手中.B在关系中没有发言权。因此,如果我想将B移动到其他地方,A必须放弃B才能将B移开。因此,在选择拥有方时,您应该考虑将要对象进行的操作。
#1
8
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.
我没有看到代码有什么不优雅。它在所有情况下都能正常工作,并且不会做任何不应该做的额外的事情。当我说A拥有的一方是AB的关系时,这意味着创建或删除关系掌握在A的手中.B在关系中没有发言权。因此,如果我想将B移动到其他地方,A必须放弃B才能将B移开。因此,在选择拥有方时,您应该考虑将要对象进行的操作。