Hibernate Batch Cascade Удалить коллекцию - PullRequest
3 голосов
/ 28 декабря 2010

К сожалению, Oracle (по крайней мере, версия, которую я использую) не поддерживает автоматическое каскадное удаление. Дочерние записи должны быть удалены отдельно перед удалением родительских записей, чтобы избежать нарушений ограничений?

При удалении родительского объекта с CascadeType.DELETE, установленной для @OneToMany, когда Hibernate решает между удалением каждого дочернего экземпляра по одному и удалением по внешнему ключу в пакете.

Например,

РОДИТЕЛЬСКИЙ стол:

PARENT_ID

1

2

ДЕТСКИЙ стол:

CHILD_ID PARENT_ID

1 1

2 1

3 2

Удаление родителя может каскадно удалить детей двумя способами:

delete from CHILD where child_id = 1
delete from CHILD where child_id = 2
delete from PARENT where parent_id = 1

или

delete from CHILD where parent_id = 1
delete from PARENT where parent_id = 1

Я видел, как Hibernate делал оба вида. Чего я не понимаю, так это как Hibernate решает, какую стратегию использовать. Похоже, что если коллекция на самом деле инициализирована, то, скорее всего, отдельные удаляются в первом примере. Тем не менее, это может привести к ошибкам ConstraintViolationException, если коллекция не соответствует тому, что находится в сеансе.

1 Ответ

2 голосов
/ 28 декабря 2010

Я не могу ответить на Hibernate часть вашего вопроса.Но вы также упомянули:

"Oracle (по крайней мере, версия, которую я использую) не поддерживает автоматическое каскадное удаление"

, и это та часть, с которой я могу противоречитьпример.

Сначала настройте таблицы с ограничениями первичного ключа:

SQL> create table parent (id)
  2  as
  3  select 1 from dual union all
  4  select 2 from dual
  5  /

Table created.

SQL> alter table parent
  2    add constraint parent_pk
  3    primary key (id)
  4  /

Table altered.

SQL> create table child (id, parent_id)
  2  as
  3  select 1, 1 from dual union all
  4  select 2, 1 from dual union all
  5  select 3, 2 from dual
  6  /

Table created.

SQL> alter table child
  2    add constraint child_pk
  3    primary key (id)
  4  /

Table altered.

Возможно, у вас есть обычное ограничение внешнего ключа:

SQL> alter table child
  2    add constraint child_parent_fk
  3    foreign key (parent_id)
  4    references parent(id)
  5  /

Table altered.

И выпосмотрите, что каскадное удаление не работает:

SQL> delete parent
  2   where id = 1
  3  /
delete parent
*
ERROR at line 1:
ORA-02292: integrity constraint ([schema].CHILD_PARENT_FK) violated - child record found

Но, если вы определяете ограничение внешнего ключа с помощью предложения ON DELETE CASCADE ...

SQL> alter table child
  2    drop constraint child_parent_fk
  3  /

Table altered.

SQL> alter table child
  2    add constraint child_parent_fk
  3    foreign key (parent_id)
  4    references parent(id)
  5    on delete cascade
  6  /

Table altered.

... then childзаписи удаляются автоматически при удалении родителя:

SQL> select * from parent
  2  /

        ID
----------
         1
         2

2 rows selected.

SQL> select * from child
  2  /

        ID  PARENT_ID
---------- ----------
         1          1
         2          1
         3          2

3 rows selected.

SQL> delete parent
  2   where id = 1
  3  /

1 row deleted.

SQL> select * from parent
  2  /

        ID
----------
         2

1 row selected.

SQL> select * from child
  2  /

        ID  PARENT_ID
---------- ----------
         3          2

1 row selected.

С уважением, Роб.

...