複合キーの設定

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でも同様に設定することができる。