Краткое
Мне интересно, что я должен делать, поскольку я прочитал много статей, пытающихся понять это, в том числе много вопросов SO. Ничто из того, что я прочитал, не поразило гвоздь на голове этим.
Я хочу знать, что происходит, когда база данных определяется каскадными правилами, а также приложение, так как это определит, должен ли я использовать следующий подход.
Примеры таблиц
create table foo(
id int unsigned not null auto_increment,
primary key(id)
);
create table bar(
id int unsigned not null auto_increment,
foo_id int unsigned not null,
primary key(id),
foreign key(foo_id) references foo(id) on delete cascade on update cascade
)
Примеры классов
@Entity
@Table(name = "foo")
public class Foo {
private int id;
private List<Bar> bars;
@Id
@GeneratedValue
@Column(name = "id")
public int getId() {
return id;
}
@OneToMany(mappedBy = "foo", cascade = {CascadeType.ALL})
public List<Bar> getBars() {
return bars;
}
public void setId() {
this.id = id;
}
public void setBars(List<Bar> bars) {
this.bars = bars;
}
}
@Entity
@Table(name = "bar")
public class Bar {
private int id;
private Foo foo;
@Id
@GeneratedValue
@Column(name = "id")
public int getId() {
return id;
}
@ManyToOne
@JoinColumn(name = "foo_id", nullable = false)
public getFoo() {
return foo;
}
public void setId(int id) {
this.id = id;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
Вопросы
Если я теперь вызываю операцию удаления (будь то через EntityManagerFactory
или SessionFactory
) в объекте Foo
, что из следующего произойдет?
-
Операция спящего режима приведет к удалению всех записей в таблице
bar
внешним ключом которого являетсяFoo
foo_id
, а затем удалить записьFoo
. -
Операция спящего режима удалит все соответствующие записи
bar
, которые были загружены в кеш сеанса (который могут или не могут быть всеbar
записи, которые существуют в фактической базе данных) и затем удалите записьFoo
(правило каскада базы данных затем удалит все оставшиеся записиbar
). -
Операция спящего режима будет пытаться сначала удалите запись
Foo
, а если сбой базы данных, выполните одно из вышеупомянутые шаги. -
Что-то еще происходит, для которого я не рассматривал, если да что?
Принимая во внимание следующие допущения дилеммы, какой наилучший подход?
Dilemna
Если 1 истинно, это предполагает:
A) Определить каскадное правило только в базе данных. Обязательно удалите bars
из объекта в приложении, чтобы они не были отделены от базы данных (поскольку база данных удалит их записи), затем сделайте вызов для удаления Foo
.
ИЛИ
B) Определить каскадное правило в приложении только потому, что он полностью контролирует целостность базы данных.
НЕ
C) Определите каскадные правила в обоих случаях, так как каждый достигнет желаемого результата, сделав другой ненужной обработкой.
Если 2 истинно, это предполагает:
Определите каскадные правила как в базе данных, так и в приложении, чтобы Hibernate мог позаботиться об управлении своими сущностями, и база данных может очиститься после того, как приложение не гарантирует удаление всех записей bar
.
Если значение 3 истинно, это предполагает:
Определите каскадные правила как в базе данных, так и в приложении, так как Hibernate, похоже, поддерживает правило каскада, которое уже определено на уровне базы данных.
Если значение 4 истинно, это предполагает:
Этот вопрос еще более важен, поскольку я пропустил что-то фундаментальное!
Изменить: Добавить статьи, которые я прочитал...
Статьи по теме
Конфликтные представления для базы данных, приложения или обоих:
SO-should-i-let-jpa-or-the- базы данных каскадных удалений
Конфликтные представления для базы данных или приложения:
SO-cascading-deletes-updates-using-jpa-or- внутри-из-баз данных
Эта статья проливает свет на то, что на самом деле делают провайдеры JPA (хотя следует отметить, что они используют провайдера OpenJPA для подтверждения своих операций):
В нем указано, что:
Каскадирование операций удаления и сохранения применяется также к тем объекты, которые еще не загружены. Он даже проходит через них другие объекты, потенциально проходящие через весь граф объекта.
Далее говорится:
Каскадирование обновления, слияния и отсоединения проходит только через объекты, которые уже загружены.
Это означало бы, что предлагаемый процесс 2 не соответствует действительности.