回答:
では、フィールドアクセス演算子を使用して主キーオブジェクト全体にアクセスすることはできない@EmbeddedIdため、これはおそらくより冗長@IdClassです。を使用すると、@EmbeddedId次のようになります。
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
これにより、複合キーを構成するフィールドがすべてフィールドアクセス演算子を介してアクセスされるクラスに集約されるため、フィールドの概念が明確になります。
@IdClassと@EmbeddedIdのもう1つの違いは、HQLを記述する場合です。
@IdClassあなたが書きます:
従業員eからe.nameを選択します
そして@EmbeddedIdあなたと一緒に書く必要があります:
従業員eからe.employeeId.nameを選択します
同じクエリに対してさらにテキストを書く必要があります。これは、によって促進された言語のようなより自然な言語とは異なると主張する人もいIdClassます。しかし、ほとんどの場合、特定のフィールドが複合キーの一部であることをクエリから正しく理解することは、非常に役立ちます。
@IdClass@Gauravによって指定された注釈は、JPA仕様のリスト複合キーを作成するための両方の方法それは非常に理由..です@IdClassと@EmbeddidId
複合主キーを使用するには、3つの方法があります。
@Embeddableし、エンティティクラスに、でマークされた通常のプロパティを追加します@Id。@EmbeddedId。@Id、でマークし、でエンティティクラスをマークして@IdClass、プライマリキークラスのクラスを提供します。@Idとしてマークされたクラスでの使用@Embeddableは、最も自然なアプローチです。いずれにしても、@Embeddableタグは非主キーの埋め込み可能な値に使用できます。複合主キーを単一のプロパティとして扱うことができ@Embeddable、他のテーブルでクラスを再利用できます。
次に最も自然なアプローチは、@EmbeddedIdタグの使用です。ここでは、主キークラスは@Embeddableエンティティではないため、他のテーブルでは使用できませんが、キーをいくつかのクラスの単一の属性として扱うことができます。
最後に、@IdClassおよび@Idアノテーションを使用すると、主キークラスのプロパティの名前に対応するエンティティ自体のプロパティを使用して、複合主キークラスをマップできます。名前は対応している必要があり(これをオーバーライドするメカニズムはありません)、主キークラスは他の2つの手法と同じ義務を果たす必要があります。このアプローチの唯一の利点は、主キークラスの使用を、囲んでいるエンティティのインターフェースから「隠す」能力です。@IdClass注釈は、化合物の主キーとして使用するクラスでなければならないクラス型の値パラメータをとります。使用する主キークラスのプロパティに対応するフィールドには、すべてで注釈を付ける必要があります@Id。
IdClassの代わりにEmbeddedIdを使用する必要があるインスタンスを発見しました。このシナリオでは、追加の列が定義されている結合テーブルがあります。結合テーブルの行を明示的に表すエンティティのキーを表すためにIdClassを使用してこの問題を解決しようとしました。このように機能させることができませんでした。ありがたいことに、「Hibernateを使用したJava Persistence」には、このトピック専用のセクションがあります。提案されたソリューションの1つは私のものと非常に似ていましたが、代わりにEmbeddedIdを使用しました。本のオブジェクトをモデルにして、オブジェクトが正しく動作するようになりました。
私の知る限り、複合PKにFKが含まれている場合は、使用する方が簡単で簡単です @IdClass
では@EmbeddedId、あなたは、二回でoneceあなたのFKの列のマッピングを定義する必要が@Embeddedableすなわちとしてのために、一度@ManyToOneどこ@ManyToOne(読み取り専用する必要があり@PrimaryKeyJoinColumnます2つの変数(競合の可能性)での1つの列セットを持つことができないために)。
したがって、で単純型を使用してFKを設定する必要があります@Embeddedable。
OneToOneおよびManyToOne関係を介し@IdClassた主キーに示すように、この状況を使用する他のサイトでは、はるかに簡単に処理できます。
JPA 2.0 ManyToOne idアノテーションの例
...
@Entity
@IdClass(PhonePK.class)
public class Phone {
@Id
private String type;
@ManyToOne
@Id
@JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
private Employee owner;
...
}
JPA 2.0 idクラスの例
...
public class PhonePK {
private String type;
private long owner;
public PhonePK() {}
public PhonePK(String type, long owner) {
this.type = type;
this.owner = owner;
}
public boolean equals(Object object) {
if (object instanceof PhonePK) {
PhonePK pk = (PhonePK)object;
return type.equals(pk.type) && owner == pk.owner;
} else {
return false;
}
}
public int hashCode() {
return type.hashCode() + owner;
}
}
主な利点は@GeneratedValue、@IdClass?を使用するときにidに使用できることです。私は、我々が使用することはできません確信している@GeneratedValueため@EmbeddedId。
@IdClass私が好みますが、ユニークなユースケースを1つ追加したいと思います@EmbeddedId(Antonio Goncalvesのセッションからこれを知るようになりました。彼が提案したことは@IdClass、キークラスはアクセスできないか、これらのシナリオは、.IN我々は注釈を追加することはできません別のモジュールまたはレガシーコードから入って来@IdClass私たちの道私たちを与えるだろう。