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?
In JPA we use the @ManyToMany annotation to model many-to-many relationships. This type of relationship can be unidirectional or bidirectional: In a unidirectional relationship only one entity in the relationship points the other. In a bidirectional relationship both entities point to each other.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With