Hibernate - how to delete bidirectional many-to-many association

Posted by slomir on Stack Overflow See other posts from Stack Overflow or by slomir
Published on 2011-04-27T21:15:06Z Indexed on 2011/11/18 17:51 UTC
Read the original article Hit count: 409

Filed under:
|
|

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?

© Stack Overflow or respective owner

Related posts about hibernate

Related posts about delete