複合主キーがあります(IDHOLIDAYPACKAGE, IDHOLIDAYPACKAGEVARIANT)
in table HolidayPackageVariant
where IDHOLIDAYPACKAGE
はエンティティHolidayPackageを参照し、Many to OneHolidayPackageVariantとHolidayPackageの間の関係。
HolidayPackageVariantで圧縮PKマッピングを実行しようとすると、次のエラーが発生します。
SessionFactoryの最初の作成に失敗しました。org.hibernate.annotations.common.AssertionFailure:宣言クラスが継承状態階層に見つかりません:org.wah.model.holidaypackage.HolidayPackageVariantPrimaryKey
誰かが私がここで間違っていることを教えてもらえますか?
私のPOJOは次のようになります。
HolidayPackageVariant:
@Entity
@Table(name="HOLIDAYPACKAGEVARIANT")
public final class HolidayPackageVariant {
private HolidayPackageVariantPrimaryKey idCompound;
@EmbeddedId
public HolidayPackageVariantPrimaryKey getIdCompound() {
return idCompound;
}
// other code
}
HolidayPackageVariantPrimaryKey
@Embeddable
public final class HolidayPackageVariantPrimaryKey implements Serializable {
private Integer idHolidayPackageVariant;
private HolidayPackage holidayPackage;
public HolidayPackageVariantPrimaryKey(){}
public HolidayPackageVariantPrimaryKey(int id, HolidayPackage pkg){
setIdHolidayPackageVariant(id);
setHolidayPackage(pkg);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "IDHOLIDAYPACKAGEVARIANT", nullable = false)
public Integer getIdHolidayPackageVariant() {
return idHolidayPackageVariant;
}
@Id
@ManyToOne(fetch=FetchType.LAZY, cascade={CascadeType.ALL})
@JoinColumn(name="IDHOLIDAYPACKAGE", nullable=false)
public HolidayPackage getHolidayPackage() {
return holidayPackage;
}
// equals and hashCode
}
HolidayPackage
public final class HolidayPackage {
private Set<HolidayPackageVariant> holidayPackageVariants = new HashSet<HolidayPackageVariant>(0);
@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.ALL}, mappedBy = "idCompound.holidayPackage")
public Set<HolidayPackageVariant> getHolidayPackageVariants() {
return holidayPackageVariants;
}
// other code
}
@Id
(EmbeddedId
クラス)。 Id
のHolidayPackageVariantPrimaryKey
アノテーションを削除すると、正常に機能するはずです。
私は@EmbeddedId
で一度戦っており、@IdClass
で同じ目標を達成しました。違いは、@IdClass
を使用する場合、クラス定義では使用しませんが、同じフィールドを再宣言します(ただし、IDフィールドにゲッター/セッターを直接指定しているので、より快適です)。 。
これが私の例です。私がポーランド政府機関GUSから自由に利用できる住所データベースを処理するために使用するプロジェクトから:
複合キー:
@Embeddable
class GusPowiatPK implements Serializable {
private static final long serialVersionUID = 1L;
private Short powiatNr;
private GusWojewodztwo wojewodztwo;
@Column(name = "POW_NR")
public Short getPowiatNr() {
return powiatNr;
}
public void setPowiatNr(Short powiatNr) {
this.powiatNr = powiatNr;
}
@ManyToOne
@JoinColumn(name = "WOJ_ID")
public GusWojewodztwo getWojewodztwo() {
return wojewodztwo;
}
public void setWojewodztwo(GusWojewodztwo wojewodztwo) {
this.wojewodztwo = wojewodztwo;
}
}
それを使用するクラス(郡):
@Entity
@Table(name = "POWIAT")
@IdClass(GusPowiatPK.class)
public class GusPowiat {
private Short powiatNr;
private GusWojewodztwo wojewodztwo;
private String nazwa;
private Date stanNa;
private boolean powiatMiejski;
public GusPowiat() {
super();
}
public GusPowiat(Short powiatNr, GusWojewodztwo wojewodztwo) {
super();
this.powiatNr = powiatNr;
this.wojewodztwo = wojewodztwo;
}
@Id
public Short getPowiatNr() {
return powiatNr;
}
public void setPowiatNr(Short powiatNr) {
this.powiatNr = powiatNr;
}
@Id
public GusWojewodztwo getWojewodztwo() {
return wojewodztwo;
}
public void setWojewodztwo(GusWojewodztwo wojewodztwo) {
this.wojewodztwo = wojewodztwo;
}
@Column(name = "NAZWA", length = 50, nullable = false)
public String getNazwa() {
return nazwa;
}
public void setNazwa(String nazwa) {
this.nazwa = nazwa;
}
@Temporal(TemporalType.DATE)
@Column(name = "STAN_NA", nullable = false)
public Date getStanNa() {
return stanNa;
}
public void setStanNa(Date stanNa) {
this.stanNa = stanNa;
}
@Column(name = "POW_MIEJSKI")
public boolean isPowiatMiejski() {
return powiatMiejski;
}
public void setPowiatMiejski(boolean powiatMiejski) {
this.powiatMiejski = powiatMiejski;
}
}
複合キーを構成するクラス(州):
@Entity
@Table(name = "WOJEWODZTWO")
public class GusWojewodztwo {
private Short id;
private String nazwa;
private Date stanNa;
public GusWojewodztwo() {
super();
}
public GusWojewodztwo(Short id) {
super();
this.id = id;
}
@Id
@Column(name = "WOJ_ID")
public Short getId() {
return id;
}
public void setId(Short id) {
this.id = id;
}
@Column(name = "NAZWA", length = 50, nullable = false)
public String getNazwa() {
return nazwa;
}
public void setNazwa(String nazwa) {
this.nazwa = nazwa;
}
@Temporal(TemporalType.DATE)
@Column(name = "STAN_NA", nullable = false)
public Date getStanNa() {
return stanNa;
}
public void setStanNa(Date stanNa) {
this.stanNa = stanNa;
}
}
エンティティクラスまたはマップされたスーパークラスの永続フィールドまたはプロパティに適用され、埋め込み可能なクラスである複合主キーを示します。埋め込み可能クラスには、埋め込み可能という注釈を付ける必要があります。 EmbeddedIdアノテーションを使用する場合、EmbeddedIdアノテーションは1つだけで、Idアノテーションは存在してはなりません。
AttributeOverrideアノテーションを使用して、埋め込み可能クラス内で宣言された列マッピングをオーバーライドできます。
MapsIdアノテーションは、EmbeddedIdアノテーションと組み合わせて使用して、派生した主キーを指定できます。
エンティティに派生主キーがある場合、AttributeOverrideアノテーションは、親エンティティとの関係に対応しない埋め込みIDの属性をオーバーライドするためにのみ使用できます。