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

У меня есть пользователь и набор авторитетов в отношениях "один ко многим":

Пользователь.hbm.xml:

<set name="authorities" table="authorities" cascade="all-delete-orphan">
    <key column="user_id" />
    <one-to-many class="com.ebisent.domain.Authority" />
</set>

Когда я удаляю пользователя, я также хочу удалить полномочия, но вместо этого внешний ключ дочерней таблицы (authorities.user_id) устанавливается равным нулю. Затем я получаю следующую ошибку, и удаление пользователя откатывается:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

Однако обновление author.user_id до нуля не откатывается.

Как я могу удалить Полномочия при удалении родительского Пользователя?

РЕДАКТИРОВАТЬ: я получил это, явно удалив полномочия, вызвав refresh() для пользователя, а затем удалив пользователя, но я хотел бы знать «правильный» способ сделать это.


person outis    schedule 19.09.2010    source источник


Ответы (1)


Это странно, каскад all-delete-orphan должен каскадировать операцию delete от родителя к дочерним. Таким образом, для удаления детей должно быть достаточно:

Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();

Получаете ли вы другой результат при использовании all,delete-orphan или даже проще delete (вы не должны). Является ли ассоциация двунаправленной? Если да, не могли бы вы показать другую сторону и соответствующее отображение?

Ассоциация только от родителя к ребенку, и я получаю одинаковые результаты со всеми, удалением-сиротой и удалением, НО... у меня не было session.flush(), и это, похоже, решает проблему.

Явный сброс может помочь. Но это не должно быть необходимо. Я думаю, что определение внешнего ключа как не допускающего значения NULL помогло бы получить правильное поведение:

<set name="authorities" table="authorities" cascade="all-delete-orphan">
    <key column="user_id" not-null="true"/>
    <one-to-many class="com.ebisent.domain.Authority" />
</set>

Хотя не проверял.

person Pascal Thivent    schedule 19.09.2010
comment
Разве вам не понадобится inverse=true для отношения, чтобы фактически удалить дочерние записи? - person nos; 19.09.2010
comment
Привет, Паскаль, нет. Ассоциация только от родителя к ребенку, и я получаю одинаковые результаты со всеми, удалением-сиротой и удалением, НО... у меня не было session.flush(), и это, похоже, решает проблему. Спасибо! - person outis; 19.09.2010
comment
@nos IMO, inverse=true не должно быть необходимо с однонаправленной ассоциацией. - person Pascal Thivent; 19.09.2010