複合キーをマップするには、EmbeddedId
またはIdClass
注釈を使用できます。この質問は厳密にはJPAに関するものではありませんが、仕様で定義されたルールも適用されます。だからここにある:
2.1.4 主キーとエンティティ ID
...
複合主キーは、以下で説明するように、単一の永続フィールドまたはプロパティ、またはそのようなフィールドまたはプロパティのセットのいずれかに対応する必要があります。複合主キーを表すには、主キー クラスを定義する必要があります。通常、複合主キーは、データベース キーが複数の列で構成されている場合に、レガシー データベースからマッピングするときに発生します。および
注釈は、複合主キーを示すために使用されます。EmbeddedId
IdClass
セクション 9.1.14 および 9.1.15 を参照してください。
...
複合主キーには次の規則が適用されます。
- 主キー クラスはパブリックである必要があり、引数なしのパブリック コンストラクターが必要です。
- プロパティ ベースのアクセスを使用する場合、主キー クラスのプロパティは public または protected である必要があります。
- 主キー クラスは である必要があります
serializable
。
- 主キー クラスはメソッドを定義する必要があり
equals
ますhashCode
。これらのメソッドの値の等価性のセマンティクスは、キーがマップされるデータベース タイプのデータベースの等価性と一致している必要があります。
- 複合主キーは、埋め込み可能なクラスとして表されてマップされるか (セクション 9.1.14「EmbeddedId アノテーション」を参照)、エンティティ クラスの複数のフィールドまたはプロパティに表されてマップされる必要があります (セクション 9.1.15「IdClass を参照してください)」。注釈」)。
- 複合主キー クラスがエンティティ クラスの複数のフィールドまたはプロパティにマップされている場合、主キー クラスの主キー フィールドまたはプロパティの名前と、エンティティ クラスの主キー フィールドまたはプロパティの名前が一致し、それらの型が同じである必要があります。
とIdClass
複合主キーのクラスは次のようになります (静的内部クラスの可能性があります)。
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, Integer confPathID) {
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals, hashCode
}
そしてエンティティ:
@Entity
@IdClass(TimePK.class)
class Time implements Serializable {
@Id
private Integer levelStation;
@Id
private Integer confPathID;
private String src;
private String dst;
private Integer distance;
private Integer price;
// getters, setters
}
IdClass
注釈は、複数のフィールドをテーブル PK にマップします。
とEmbeddedId
複合主キーのクラスは次のようになります (静的内部クラスの可能性があります)。
@Embeddable
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, Integer confPathID) {
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals, hashCode
}
そしてエンティティ:
@Entity
class Time implements Serializable {
@EmbeddedId
private TimePK timePK;
private String src;
private String dst;
private Integer distance;
private Integer price;
//...
}
注釈は@EmbeddedId
、PK クラスをテーブル PK にマップします。
違い:
- 物理モデルの観点からは、違いはありません
@EmbeddedId
キーが複合キーであり、結合された pk が意味のあるエンティティ自体であるか、コードで再利用されている場合、 IMO は理にかなっています。
@IdClass
フィールドのいくつかの組み合わせが一意であることを指定するのに役立ちますが、これらには特別な意味はありません。
また、クエリの記述方法にも影響します (多かれ少なかれ冗長になります)。
参考文献
- JPA 1.0 仕様
- 2.1.4項「主キーとエンティティID」
- 9.1.14項「EmbeddedId注釈」
- 9.1.15項「IdClass注釈」