级联变化

All lectures for ZH purposes
第 1 级 , 课程 852
可用

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.REFRESHCascadeType.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.LAZY
  • FetchType.EAGER

这是一个非常有趣的话题,有各种陷阱,所以我最好单独讲一讲。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION