當資料表主鍵由多個欄位組成時,需建立複合主鍵類別。Hibernate 提供兩種方式:@IdClass (主鍵類別獨立) 與 @EmbeddedId (主鍵類別內嵌)。本文以 @IdClass 為例說明。
主鍵類別需:
@EmbeddableSerializableequals() 與 hashCode()@Embeddable
public class UserPK implements Serializable {
private int id;
private int id2;
// getter/setter、equals、hashCode 略
}
@Entity
@Table(name = "E_USER", uniqueConstraints = @UniqueConstraint(columnNames = "yahoo"))
@IdClass(UserPK.class)
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 注意:複合主鍵通常不適用 IDENTITY
private int id;
@Id
private int id2;
private String yahoo;
// getter/setter 略
}
create table E_USER (
id integer not null,
id2 integer not null,
yahoo varchar(255),
primary key (id, id2),
unique (yahoo)
)
@Entity
public class User {
@EmbeddedId
private UserPK id; // 直接內嵌主鍵物件
private String yahoo;
// ...
}
此方式實體不再有分散的 @Id 欄位,而是單一 id 物件屬性,存取時需 user.getId().getId(),語意更清晰。
equals/hashCode,否則 Session 快取查找、Set/Map 操作會失效。@GeneratedValue 於複合主鍵通常不適用,主鍵值需由應用層指派或使用自訂產生器。@Id 欄位加 @Column(name = "db_column"),主鍵類別屬性名仍保持一致。