Psy*_*rus 17 java mysql database hibernate 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
)
Run Code Online (Sandbox Code Playgroud)
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我现在在对象上调用删除操作(通过EntityManagerFactory或SessionFactory)Foo,将发生以下哪种情况?
hibernate操作将删除bar表中外键为Foos的所有记录foo_id,然后删除Foo记录.
hibernate操作将删除Bar已加载到会话缓存中的所有相应记录(可能是也可能不是bar实际数据库中存在的所有记录),然后删除Foo记录(数据库级联规则将删除任何剩余bar记录).
hibernate操作将首先尝试删除Foo记录,如果数据库失败,则执行上述步骤之一.
我还没有考虑过其他事情,如果是这样的话?
考虑到以下困境假设,最佳方法是什么?
如果1为真,那么它会建议:
A)仅在数据库中定义级联规则.确保bars从应用程序中的对象中删除它们,使它们不会与数据库分离(因为数据库将删除它们的记录),然后调用delete foo.
要么
B)仅在应用程序中定义级联规则,因为它将彻底管理数据库完整性.
不
C)在两者中定义级联规则,因为每个都实现了期望的结果,使得另一个浪费了处理.
如果2为真,那么它会建议:
在数据库和应用程序中定义级联规则,以便Hibernate可以负责管理其实体,并且数据库可以在应用程序无法保证删除所有bar记录后进行清理.
如果3为真,那么它会建议:
在数据库和应用程序中定义级联规则,因为Hibernate似乎支持已在数据库级别定义的级联规则.
如果4为真,那么它会建议:
这个问题更重要,因为我错过了一些基本的东西!
编辑:添加我读过的文章...
数据库,应用程序或两者的视图冲突:
数据库或应用程序的冲突视图:
SO - 级联 - 删除 - 更新 - 使用-jpa或数据库内部
本文阐明了JPA提供商实际做了什么(尽管应该注意他们使用OpenJPA提供商来证明他们的运营):
它指出:
remove和persist操作的级联也适用于尚未加载的实体.它甚至将它们传递给其他实体,可能遍历整个对象图.
它继续说:
刷新,合并和分离的级联仅通过已加载的实体传递.
这意味着提议的流程2不成立.
小智 3
如果您在数据库中声明级联并休眠,则数据库将始终首先删除(如果它支持),并且休眠调用不会真正删除任何内容,而是无论如何都会运行。然而,由于您使用的是 hibernate,它的主要优点是可以轻松过渡到可能不支持数据库端级联功能的新数据库。因此,即使您的数据库支持级联并且 hiberate 下划线 jdbc 语句当前没有执行任何操作(它们将来可能会执行某些操作),您也希望将它们留在那里