как определить обратное каскадное удаление в отображении «многие к одному» в спящем режиме - PullRequest
18 голосов
/ 11 ноября 2009

У меня есть два класса A и B. Многие B могут иметь связь с одним A, следовательно, отношение «многие к одному» от B до A. Я отобразил отношения как:

<class name="A" table="tbl_A">
  <property name="propA" column="colA"/>
</class>
<class name="B" table="tbl_B">
  <property name="propB" column="colB"/>
  <many-to-one name="a" class="A" column="col1" cascade="delete"/>
</class>

A не имеет ничего связанного с B. Имея это в виду, мы намереваемся удалить B, когда связанный с ним A удален. Это было бы возможно, если бы я мог определить inverse = "true" для связи "многие-к-одному" в B, но hibernate не позволяет этого.

Может кто-нибудь помочь с этим? Мы не хотим ничего писать для этого.

Ответы [ 2 ]

24 голосов
/ 11 ноября 2009

Hibernate только каскады вдоль определенных ассоциаций. Если A ничего не знает о Bs, то ничего, что вы делаете с A, не повлияет на Bs.

Поэтому предложение Паскаля - самый простой способ сделать то, что вы хотите:

<class name="A" table="tbl_A">
  ...
  <set name="myBs" inverse="true" cascade="all,delete-orphan">
    <key column="col1"/>
    <one-to-many class="B"/>
  </set>
</class>

<class name="B" table="tbl_B">
  ...
  <many-to-one name="a" class="A" column="col1" not-null="true"/>
</class>

Обратите внимание, что установка cascade="delete" на B в том виде, в каком она есть в исходном коде, НЕ будет делать то, что вы хотите - она ​​говорит Hibernate «удалить A, если B удален», что может привести к нарушению ограничения (если есть другие B, связанные с этим A).

Если вы абсолютно не можете добавить коллекцию B к A (хотя я не могу вспомнить обстоятельства, при которых это имело бы место), ваша единственная другая альтернатива - определить каскадное удаление из A в B в иностранном ключевой уровень; ваш B будет удален, когда ваш A будет удален.

Это довольно уродливое решение, потому что вы должны быть очень осторожны с тем, как вы удаляете A в Hibernate:

  1. Сессия должна быть сброшена перед удалением A (наличие ожидающих обновлений B может привести к ошибке или к тому, что A и некоторые B будут повторно вставлены за кулисы)
  2. Все B, связанные с вашей A (и поскольку вы не поддерживаете отношения со стороны A, что означает все B), должны быть удалены из всех активных сессий и кэша 2-го уровня.
7 голосов
/ 11 ноября 2009

Я думаю, вам нужно cascade="all,delete-orphan" от А до Б с one-to-many ассоциацией.

...