複合キーを持つエンティティがあるので、@ Embeddableおよび@EmbeddedIdアノテーションを使用します。埋め込み可能なクラスは次のようになります。
@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {
@ManyToOne
@JoinColumn(name = "admin_id")
private DitaAdmin admin;
@ManyToOne
@JoinColumn(name = "account_id")
private DitaAccount account;
//constructor, getters, setters...
}
そしてそれを使用するエンティティ:
@Entity
public class DitaAdminAccountSkill {
@EmbeddedId
private DitaAdminAccountSkillPK id;
//constructor, getters, setters...
}
次のように、エンティティを別のエンティティにマップします。
@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.admin")
private List<DitaAdminAccountSkill> accountSkills;
に注意してください mappedBy = "id.admin" これは 管理者 のフィールド DitaAdminAccountSkillPK を使用して id の分野 DitaAdminAccountSkill。
これはコンパイルして問題なく実行されます。ただし、Eclipseでは、次のエラーが表示されます。 属性「accountSkills」で、「マップされた」値「id.admin」をターゲットエンティティの属性に解決できません。
これは JPAの問題 JPAファセットが不平を言っていることを意味します。今、私は代わりに@IdClassを使用できることを知っていますが、なぜそれがエラーであると思うのですか?それとも私はひどく間違っている何かをしますか?
JPA 2.0仕様のセクション11.1.15によれば、 :埋め込みIDクラス内で定義された関係マッピングはサポートされていません。ただし、これはかもしれないたとえそれ自体が規格自体によって正式にサポートされていなくても、使用しているJPA実装によってサポートされています。
これが当てはまる場合は、EclipseでWindow -> Preferences -> Java Persistence -> JPA -> Errors/Warnings -> Attributes -> Cannot resolve attribute name
。
私の場合、以下をIgnore
に設定するまで問題は解決しませんでした:
Project Facets > JPA > Errors/Warnings > Type > Mapped Java Class is a member class
以前の解決策を試す前に、まずpersistence.xml
およびexclude-unlisted-classes
がtrue
に設定されているか、マップされたすべてのクラスがpersistence-unit
。
JPA 2.0仕様に準拠しており、同じように機能するように見えるソリューションを投稿すると思いました。
まず、JPA 2.0仕様は次の場所にあります: JSR-000317 Eval 2.0 Eval の永続性仕様。関連するセクションは、2.4.1「派生IDに対応する主キー」になります。
指定したクラスを使用した例を次に示します。
埋め込みIDクラス:
@Embeddable
public class DitaAdminAccountSkillPK implements Serializable {
//No further annotations are needed for the properties in the embedded Id.
//Needs to match the type of the id of your DitaAdmin object. I added 'Id' to the end of the property name to be more explicit.
//Making the assumption here that DitaAdmin has a simple Integer primary key.
private Integer adminId;
//Needs to match the type of the id of your DitaAccount object. I added 'Id' to the end of the property name to be more explicit.
//Making the assumption here that DitaAccount has a simple Integer primary key.
private Integer accountId;
//I'm adding a third property to the primary key as an example
private String accountName;
//constructor, getters, setters...
//hashCode() and equals() overrides
}
「依存」エンティティクラス:
@Entity
public class DitaAdminAccountSkill {
@EmbeddedId
//Any overrides to simple Id properties should be handled with an attribute override
@AttributeOverride(name = "accountName", column = @Column(name = "account_name"))
private DitaAdminAccountSkillPK id;
//MapsId refers to the name of the property in the embedded Id
@MapsId("adminId")
@JoinColumn(name="admin_id")
@ManyToOne
private DitaAdmin admin;
@MapsId("accountId")
@JoinColumn(name="account_id")
@ManyToOne
private DitaAccount account;
//constructor, getters, setters...
}
「親」エンティティクラス:
public class DitaAdmin {
@Id
private Integer id;
//...
//Now your mappedBy attribute can refer to the admin object defined on DitaAdminAccountSkill which is also part of the Primary Key
@OneToMany(fetch = FetchType.LAZY, mappedBy="admin")
private List<DitaAdminAccountSkill> accountSkills;
//...
}
設定-> Java持続性-> JPA->エラー/警告->属性->埋め込みIDクラスに関係マッピングを含めないでください:(無視)