JPA 複合鍵實作指南
在使用 JPA 進行資料庫映射時,有些情境需要使用複合主鍵(Composite Key),特別是當實體間存在關聯關係且這些關聯本身也是主鍵的一部分時。本文將介紹如何使用 @IdClass 註解來實現複合主鍵,並著重說明如何處理嵌套的複合主鍵關係。
複合主鍵類別的定義
首先,我們需要定義代表複合主鍵的類別:
class PartPK implements Serializable {
private String partId;
private String orgId;
// 此處省略必要的構造函數、equals和hashCode方法
}
class StockPK implements Serializable {
private String storeId;
private PartPK part;
// 此處省略必要的構造函數、equals和hashCode方法
}
實體類別的實作
接著,我們實作對應的實體類別並添加適當的 JPA 註解:
@Entity
@Table(name = "parts")
@IdClass(PartPK.class)
class Part implements Serializable {
@Id
@Column(name = "PART_ID")
private String partId;
@Id
@Column(name = "PART_ORGANIZATION_ID")
private String orgId;
// 其他欄位與方法...
}
@Entity
@Table(name = "stocks")
@IdClass(StockPK.class)
class Stock implements Serializable {
@Id
@Column(name = "STORE_ID")
private String storeId;
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumns({
@JoinColumn(name = "STOCK_PART_ID", referencedColumnName = "PART_ID"),
@JoinColumn(name = "STOCK_PART_ORGANIZATION_ID", referencedColumnName = "PART_ORGANIZATION_ID"),
})
private Part part;
// 其他欄位與方法...
}
JPA 複合主鍵實作重點
-
實作 Serializable 介面:所有主鍵類別都必須實作
Serializable介面。 -
使用 @IdClass 註解:在實體類別上使用此註解指定對應的複合主鍵類別。
-
標記 @Id 欄位:實體類別中組成複合主鍵的所有欄位都必須標記為
@Id。 -
使用 @JoinColumns:當複合主鍵中包含對另一個實體的關聯時(如範例所示),
@JoinColumns允許將多個欄位映射到被參照實體的 ID 欄位。 -
實作 equals() 和 hashCode():主鍵類別應基於所有構成複合主鍵的欄位正確實作
equals()和hashCode()方法。 -
無參數建構函數:主鍵類別必須具有無參數建構函數。
此方法的優勢
- 允許自然地建模複雜的主鍵關聯
- 支援在具有複合關聯的實體之間進行導航
- 在資料庫層面維護參照完整性約束
- 啟用 JPA 的實體管理功能,例如級聯操作
這種模式在建模庫存系統、多租戶應用程式,或任何需要通過多個欄位(包括對其他實體的參照)來識別實體的領域中特別有用。