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.LAZY
FetchType.EAGER
這是一個非常有趣的話題,有各種陷阱,所以我最好單獨講一講。
GO TO FULL VERSION