JPA 休眠 - 数据库和注释中的级联删除
短
我想知道我应该怎么做,因为我已经阅读了许多试图理解这一点的文章,包括许多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
其他我没有考虑过的事情,如果是这样,该怎么办?
考虑到以下困境假设,最好的方法是什么?
迪莱姆纳
如果 1 为真,则表明:
A) 仅在数据库中定义级联规则。确保从应用程序中的对象中删除,以便它们不会与数据库分离(因为数据库将删除其记录),然后调用 delete 。bars
foo
或
B) 仅在应用程序中定义级联规则,因为它将彻底管理数据库完整性。
不
C)在两者中定义级联规则,因为每个规则都实现了预期的结果,使得另一个浪费了处理。
如果 2 为真,则表明:
在数据库和应用程序中定义级联规则,以便 Hibernate 可以负责管理其实体,并且数据库可以在之后进行清理,因为不能保证应用程序删除所有记录。bar
如果 3 为真,则表明:
在数据库和应用程序中定义级联规则,因为 Hibernate 似乎支持已在数据库级别定义的级联规则。
如果 4 为真,则表明:
这个问题更重要,因为我错过了一些基本的东西!
编辑:添加我读过的文章...
相关文章
数据库视图、应用程序视图或两者冲突:
SO - should-i-let-jpa-or-the-database-cascade-deletes
数据库或应用程序的冲突视图:
本文阐明了 JPA 提供程序的实际操作(尽管应该注意的是,他们使用 OpenJPA 提供程序作为其操作证明):
它指出:
删除和持久化操作的级联也适用于尚未加载的实体。它甚至通过它们传递到其他实体,可能会遍历整个对象图。
它继续说:
刷新、合并和分离的级联仅通过已加载的实体。
这意味着提议的过程2是不正确的。