public enum CascadeType {
ALL, // 全部級聯
PERSIST, // 保存級聯
MERGE, // 合併/更新級聯
REMOVE, // 刪除級聯
REFRESH, // 刷新級聯
DETACH // 游離級聯 (JPA 2.0+)
}
| 類型 | 觸發操作 | 級聯動作 | 典型場景 | 風險提示 |
|---|---|---|---|---|
PERSIST |
session.save()/persist() |
關聯對象若為 transient → 自動 save | 父子關係同時新建 (訂單+明細) | 關聯對象已持久化會拋異常 |
MERGE |
session.merge()/update() |
關聯對象自動 merge (新建則 save,已管則 update) | DTO 回寫實體樹、離線編輯保存 | 大對象圖性能開銷大 |
REMOVE |
session.delete()/remove() |
關聯對象自動 delete | 刪除訂單連帶刪除明細 | 極度危險:誤刪被多方引用對象 |
REFRESH |
session.refresh() |
關聯對象自動 refresh (覆蓋本地修改,同步 DB 狀態) | 併發場景二次確認、放棄本地修改 | 會丟失未提交的本地變更 |
DETACH |
session.detach()/evict() |
關聯對象自動游離 | 會話結束前主動清理緩存 | 較少直接使用 |
ALL |
以上所有操作 | 全生命周期級聯 | 緊密聚合根 (如 Order→OrderItem) | 包含 REMOVE 風險,謹慎用 |
items = new HashSet<>();
cascade 屬性值逗號分隔,支援 delete-orphan (集合專用)。cascade 為數組,orphanRemoval 獨立屬性。@Entity
public class Order {
@Id @GeneratedValue private Long id;
private String orderNo;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private Set items = new HashSet<>();
public void addItem(OrderItem item) {
items.add(item);
item.setOrder(this); // 維護雙向關聯
}
public void removeItem(OrderItem item) {
items.remove(item);
item.setOrder(null);
}
}
@Entity
public class OrderItem {
@Id @GeneratedValue private Long id;
private String sku;
private int qty;
@ManyToOne @JoinColumn(name = "order_id")
private Order order;
}
數據庫約束前提:外鍵與級聯
Hibernate 級聯僅在內存對象圖層面生效,最終 SQL 執行仍受數據庫外鍵約束。若 DB 定義
ON DELETE RESTRICT,HibernateREMOVE級聯執行 DELETE 時會拋異常。建議:
ON DELETE CASCADE,由 Hibernate 控制級聯邏輯,便於審計、攔截、事務回滾。ON DELETE RESTRICT 或 NO ACTION,作為最後防線。PERSIST, MERGE 或 save-update。@OneToMany(mappedBy=...) 端,單向關聯無效。Hibernate.initialize(set) 或 @BatchSize。CascadeType 定義了對象圖生命周期的傳遞規則。核心決策矩陣:
ALL + orphanRemovalPERSIST, MERGE (嚴禁 REMOVE)REFRESH記住:級聯是雙刃劍,用對是領域模型的強力輔助,用錯是數據災難的溫床。始終在領域建模階段明確聚合邊界,再映射級聯策略。