Как удалить двунаправленную ассоциацию «многие ко многим» - PullRequest
12 голосов
/ 28 апреля 2011

Проблема:

У меня есть связь «многие ко многим» между двумя сущностями A и B . Я установил сущность в качестве владельца их отношения (обратное = true находится в коллекции A в 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="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 отвечает за свои отношения с 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) в двунаправленной ассоциации «многие ко многим» и во всех его отношениях «многие ко многим» с совместного стола?

1 Ответ

8 голосов
/ 28 апреля 2011

Я не вижу, что не элегантно в коде.Он отлично работает во всех случаях и не делает лишних вещей, которые он не должен делать.Когда я говорю, что А владеет стороной - это отношения АВ, это будет означать, что создание или удаление отношений находится в руках А. Б не имеет права голоса в отношениях.Поэтому, если я хочу переместить B куда-нибудь еще, A должен отпустить B, прежде чем B можно будет убрать.Следовательно, при выборе стороны-владельца вы должны учитывать, что вы собираетесь делать с объектами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...