Как определить обратное каскадное удаление в отображении "многие к одному" в спящем режиме

У меня есть два класса 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 ответа

Решение

Спящие только каскады вдоль определенных ассоциаций. Если 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 удален", что может привести к нарушению ограничения (если с этим A связаны другие B).

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

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

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

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

Другие вопросы по тегам