複合キーの設定
Caution
複合キーかつ親子等の関連を持つTBLは、JPAの仕様上食い合わせが悪い。
できる限り複合キーを使用しない、または代理キーを使用するなどの工夫をすることを推奨する。
複合キーの設定方法
@IdClass + @Idアノテーションを使用するパターン
@Embeddable + @EmbeddedIdアノテーションを使用するパターン
@IdClass + @Idアノテーションを使用するパターン
@EqualsAndHashCode
public class SamplePK implements Serializable {
private String paranA;
private String paramB;
}
@IdClass(SamplePK.class)
@Table(name = "SAMPLE_TBL")
public class SampleParent {
@Id
@Column(name = "param_a")
private String paranA;
@Id
@Column(name = "param_b")
private String paramB;
@Column(name = "parent_param")
String parentParam;
}
Note
IdClassに指定したクラスの項目と、@Idアノテーションを付与した項目が一致している必要がある。
@Embeddable + @EmbeddedIdアノテーションを使用するパターン
@Embeddable
public class SamplePK implements Serializable {
@Column(name = "param_a")
private String paranA;
@Column(name = "param_b")
private String paramB;
}
@Table(name = "SAMPLE_TBL")
public class SampleParent {
@EmbeddedId
private SamplePK pk;
@Column(name = "parent_param")
String parentParam;
}
Note
PKのクラス側にも@Columnアノテーションを付与する必要がある。
Caution
@EmbeddedIdアノテーションと@Idアノテーションを同時に使用することはできない。
親子で共通の複合キーを持ちつつも、子のみに別のキーを持たせたい場合は、@IdClassアノテーションを使用する必要がある。
このパターンでは、親子で連動してPKを操作することができる
@Table(name = "SAMPLE_TBL")
public class SampleParent {
@EmbeddedId
private SamplePK pk;
@Column(name = "parent_param")
String parentParam;
@OneToOne(mappedBy = "parent", cascade = CascadeType.ALL)
private SampleChild child;
}
@Table(name = "SAMPLE_CHILD_TBL")
public class SampleChild {
@EmbeddedId
private SamplePK pk;
@Column(name = "child_param")
String childParam;
@OneToOne
@MapsId
@JoinColumns({
@JoinColumn(name = "param_a")
@JoinColumn(name = "param_b")
})
private SampleParent parent;
}
Note
上記はOneToOneの例だが、OneToManyやManyToOneでも同様に設定することができる。