2011-04-27 66 views
12

問題:如何刪除雙向許多-to-many關聯

我有兩個實體A和B之間許多-to-many關聯。 I set 一個實體作爲的所有者他們的關係(inverse = true在A的b.hbm.xml集合中)。

當i 刪除A實體時,對應的連接表中的記錄被刪除
當i 刪除B實體時,對應的連接表中的記錄不會被刪除(完整性違規異常)。

-

讓我們考慮一些很簡單的例子

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

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

文件[僅M-到米映射] a.hbm.xml

<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實體負責他的relati與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)從聯合表開始,多對多的關係和他所有的多對多關係?

+0

的可能重複[休眠:刪除許多-to-many關聯(http://stackoverflow.com/questions/2783602/hibernate-delete-many-to-many-association) – 2011-04-27 21:38:55

+0

@Don羅比 - 我認爲建議的主題是相似的,但我無法找到我的問題的答案。在那裏,作者想明確地刪除關聯。另一方面,當我刪除一些形成關聯的實體時,我想隱式地刪除關聯。我的方法的原因是m-to-m關聯中連接表的「隱含性質」。 – slomir 2011-04-27 22:12:05

回答

8

我看不出有關代碼的優雅。它在任何情況下都可以正常工作,並且不會做任何不該做的事情。當我說A是擁有方是AB關係時,這意味着創建或刪除關係在A的手中。B在關係中沒有發言權。所以如果我想把B移到別的地方,A必須放開B才能將B移開。因此,當選擇自己的一面時,你應該考慮你將如何處理這些物體。

+1

感謝您的回答。我只是想聽到這個。我是Hibernate技術的初學者,我對問題的理解並不是100%確定的,但現在沒問題。 當我提到優雅時,我認爲也許這種問題存在單行代碼解決方案,因爲連接表在某種意義上是隱式的工件,也就是說,我沒有可能從聯合表中明確刪除行本身。但關於車主的解釋澄清了事情。 – slomir 2011-04-28 11:48:36