6.1 深度依赖管理
还有一些关于@OneToMany注解之类的更有用和有趣的东西。它们都有4个常用选项:
- 级联= CascadeType.ALL
- orphanRemoval = 真
- fetch = FetchType.LAZY
现在我们将更详细地分析它们。我们将从最有趣的 - CascadeType开始。此参数确定如果我们更改主要实体,依赖实体应该发生什么。
JPA规范对该参数有如下取值:
- 全部
- 坚持
- 合并
- 消除
- 刷新
- 分离
但是,Hibernate 将此规范扩展为三个更多选项:
- 复制
- SAVE_UPDATE
- 锁
当然,数据库和它们的 CONSTRANIS 有很强的相似性。但是,也有区别。Hibernate 试图尽可能地隐藏与数据库的实际工作,因此这些 Hibernate Cascades 正是关于 Entity 对象的。
6.2 级联类型
cascade 参数描述了如果我们更改它们的父对象(主对象),依赖对象应该发生什么。大多数情况下,此参数与描述对象依赖关系的注释一起使用:
例子:
OneToOne(cascade = CascadeType.ALL)
或者像这样:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
也可以写成单独的注解:
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
现在让我们更多地讨论这些注释的含义。
6.3 全部、坚持、合并
CascadeType.ALL意味着我们对父对象执行的所有操作都必须对其依赖对象重复。
CascadeType.PERSIST意味着如果我们将父对象保存到数据库中,那么必须对它的依赖对象做同样的事情。例子:
@Entity @Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.PERSIST, mappedBy="task")
private EmployeeTask task;
}
使用此类的示例:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
session.persist(director);
session.flush();
我们只保存一个Employee类型的对象,它的依赖对象EmployeeTask会自动保存到数据库中。
CascadeType.MERGE意味着如果我们更新数据库中的父对象,则必须对其依赖对象进行相同的操作。
6.4 移除、删除、分离
CascadeType.REMOVE意味着如果我们删除数据库中的父对象,那么必须对它的依赖对象做同样的事情。
CascadeType.DELETE意思一样。这些是同义词。只是规格不同而已。
CascadeType.DETACH意味着如果我们从会话中删除父对象,则必须对其依赖对象执行相同的操作。例子:
@Entity @Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.DETACH, mappedBy="task")
private EmployeeTask task;
}
使用此类的示例:
Employee director = new Employee();
EmployeeTask task = new EmployeeTask();
director.task = task;
director.task = task;
session.flush();
assertThat(session.contains(director)).isTrue();
assertThat(session.contains(task)).isTrue();
session.detach(director);
assertThat(session.contains(director)).isFalse();
assertThat(session.contains(task)).isFalse();
CascadeType.REFRESH并 CascadeType.SAVE_UPDATE以与我们预期相同的方式工作——它们将对父对象执行的操作复制到其从属对象。
6.5 孤儿删除选项
有时您可能还会遇到参数orphan。这是孤儿移除的缩写。它用于确保不存在没有父实体的子实体。
OneToOne(orphan = true)
如果此参数设置为true,则子实体消失后将被删除所有链接. 它与 . 不完全相同Cascade.REMOVE。
您可能会遇到多个父实体引用一个子实体的情况。那么有益的是它不会随着父实体的删除而被删除,但前提是对它的所有引用都被取消。
假设你有一堂课:
@Entity @Table(name="user")
class Employee {
@Column(name="id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, orphan = true) @JoinColumn(name = "employee_id")
private Set<EmployeeTask> tasks = new HashSet<EmployeeTask>();
}
Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.tasks.get(0);
director.tasks.remove(task)
session.persist(director);
session.flush();
EmployeeTask 对象将被删除,因为没有留下任何引用。同时,没有人删除父对象。
6.6 获取选项
fetch 选项允许您控制依赖对象的加载方式。它通常采用以下两个值之一:
FetchType.LAZYFetchType.EAGER
这是一个非常有趣的话题,有各种陷阱,所以我最好单独讲一讲。
GO TO FULL VERSION