Проблема:
У меня есть связь "многие-ко-многим" между двумя объектами 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 в моем примере) в двунаправленной ассоциации "многие-ко-многим" и все его многие-ко-многим отношения из совместного стола?