Brief
我想知道我应该做什么,因为我读过很多文章试图理解这一点,包括许多 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
or SessionFactory
) on a Foo
对象,下列哪一种情况会发生?
hibernate操作会删除该目录下的所有记录bar
桌子
其外键是Foo
's foo_id
然后删除
这Foo
record.
hibernate操作会删除所有对应的Bar
已加载到会话缓存中的记录(其中
可能是也可能不是全部bar
实际数据库中存在的记录)和
然后删除Foo
记录(数据库级联规则将删除任何剩余的bar
记录)。
休眠操作将尝试
删除Foo
首先记录,如果数据库失败,则执行以下操作之一
上述步骤。
还有一些我没有考虑到的事情发生了,如果是的话怎么办?
考虑到以下困境假设,最好的方法是什么?
Dilemna
如果 1 为真,则表明:
A) 仅在数据库中定义级联规则。一定要删除bars
从应用程序中的对象中分离出来,这样它们就不会与数据库分离(因为数据库将删除它们的记录),然后调用删除foo
.
OR
B) 仅在应用程序中定义级联规则,因为它将彻底管理数据库完整性。
NOT
C) 在两者中定义级联规则,因为每个都实现了所需的结果,而使另一个浪费了处理。
如果 2 为真,则表明:
在数据库和应用程序中定义级联规则,以便 Hibernate 可以负责管理其实体,并且数据库可以在之后进行清理,因为应用程序不能保证删除所有实体bar
记录。
如果 3 为真,则表明:
在数据库和应用程序中定义级联规则,因为 Hibernate 似乎支持已在数据库级别定义的级联规则。
如果 4 为真,则表明:
这个问题更加重要,因为我错过了一些基本的东西!
编辑:添加我读过的文章...
相关文章
数据库、应用程序或两者的视图相互冲突:
SO - 应该让 jpa 或数据库级联删除 https://stackoverflow.com/questions/5787551/should-i-let-jpa-or-the-database-cascade-deletions
数据库或应用程序的冲突视图:
SO - 使用 jpa 或数据库内部进行级联删除更新 https://stackoverflow.com/questions/554750/cascading-deletes-updates-using-jpa-or-inside-of-database
本文阐明了 JPA 提供程序的实际用途(尽管应该注意的是,他们使用 OpenJPA 提供程序进行操作证明):
jpa教程 http://meri-stuff.blogspot.co.uk/2012/03/jpa-tutorial.html
它指出:
删除和持久操作的级联也适用于那些
尚未加载的实体。它甚至穿过它们
其他实体,可能会遍历整个对象图。
它接着指出:
刷新、合并和分离的级联仅通过
已经加载的实体。
这意味着提议的流程 2 不正确。