Подтвердить что ты не робот

Как удалить двунаправленную связь "многие-ко-многим"

Проблема:

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

4b9b3361

Ответ 1

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