t_customers:客戶表,含 referee_id 外鍵t_referees:推薦人表
@Entity
@Table(name = "t_customers")
public class Customer {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne
private Referee referee; // 預設外鍵欄位為 referee_id
// Getter/Setter 略...
}
@Entity
@Table(name = "t_referees")
public class Referee {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@OneToOne(mappedBy = "referee")
private Customer customer;
// Getter/Setter 略...
}
若外鍵非預設命名,可用 @JoinColumn 覆蓋:
@OneToOne
@JoinColumn(name = "referee1_id")
public Referee getReferee() { return referee; }
同時 Referee 端 mappedBy 需同步修改為 "referee1"。
移除 t_customers.referee_id,令 t_referees.id 同時作為主鍵與外鍵,值依賴 Customer 主鍵。
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Referee getReferee() { return referee; }
@OneToOne
@PrimaryKeyJoinColumn
public Customer getCustomer() { return customer; }
@Id
@GeneratedValue(generator = "pkGenerator")
@GenericGenerator(
name = "pkGenerator",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "customer")
)
public int getId() { return id; }
關鍵點:
@PrimaryKeyJoinColumn:宣告共享主鍵。@GenericGenerator(strategy = "foreign"):指定主鍵來源為關聯實體的 customer 屬性。em.persist(customer),Referee 會級聯儲存。// 外鍵模式
Customer c = new Customer(); c.setName("微軟");
Referee r = new Referee(); r.setName("趙軍");
em.persist(r);
c.setReferee(r);
em.persist(c);
// 共享主鍵模式
Customer c2 = new Customer(); c2.setName("Google");
Referee r2 = new Referee(); r2.setName("李四");
c2.setReferee(r2);
em.persist(c2); // 單獨持久化 Customer 即可