外部キーがターゲット クラスの @Embedded フィールドにリンクする ManyToOne 関係を使用しようとしています。これは正常にコンパイルおよび拡張されますが、このコードを実行すると、OpenJPA は例外を報告します。これは OpenJPA 2.0.1 を使用しています。コードでは、これは次のようになります。
@Embeddable
public class NormalizedNumber {
private String normalizedNumber;
@Basic
public String getNormalizedNumber() {
return normalizedNumber;
}
/* ... */
}
@Entity
@Table(name = "Phones")
public class Phone {
private String key;
private NormalizedNumber normalizedNumber;
@Id
@Column(name = "IdKey", nullable = false)
protected String getKey() {
return key;
}
@Embedded
public NormalizedNumber getNormalizedNumber() {
return normalizedNumber;
}
/* ... */
}
@Entity
@Table(name = "UsersPhones")
public class UserPhone {
private String key;
private Phone device;
@Id
@Column(name = "IdKey", nullable = false)
protected String getKey() {
return key;
}
@ManyToOne
@JoinColumn(name="DeviceId", referencedColumnName="NormalizedNumber")
public Phone getDevice() {
return this.device;
}
}
MySQL の対応するデータベース スキーマ:
create table Phones (
IdKey CHAR(32) BINARY,
-- type discriminator (inheritance strategy is single table)
UDType CHAR(2) BINARY,
NormalizedNumber VARCHAR(100) BINARY NOT NULL,
-- more columns here
constraint Phones_PK primary key (IdKey) );
create table UsersPhones (
IdKey CHAR(32) BINARY,
DeviceId VARCHAR(100) BINARY NOT NULL,
UserKey CHAR(32) BINARY,
-- more columns here
constraint UsersPhones_PK primary key (IdKey) );
ここで起こっていることは次のとおりです。クラスをPhone
埋め込むクラスがありNormalizedNumber
ます。normalizedNumber
ただし、 は主キーではなく、@Id
クラスの でもありません。とは異なるkey
フィールドがあり@Id
ます。
クラスには、クラスへのUserPhone
参照がありPhone
ます。@ManyToOne
多くのユーザーが同じ電話を共有できるため、これは関係です。テーブルは、 テーブルUsersPhones
の主キーをPhones
外部キーとして使用するのではなく、NormalizedNumber
列を使用します。どうやらこれは JPA では有効ではない可能性がありますが、OpenJPA のマニュアルには、OpenJPA はターゲット列が主キーではない結合を「主キー結合と同じ構文で」サポートすると記載されています。
マニュアルから、これは埋め込みフィールドでも機能すると信じるようになりました。しかし、そうではないので、私はそれを誤解したに違いないと思います。これは私が得る例外です:
「列 'Phones.normalizedNumber' に結合できません。結合をサポートするマッピングによって管理されていません。」
私は今、デバッガーを使用して OpenJPA を 2 日間調べ、何か間違ったことをした場合、またはドキュメントに明示的に記載されていないために合法ではない場合のヒントを見つけました。Javadoc で、OpenJPAEmbedFieldStrategy
が実装していないというヒントを見つけましたJoinable
。だから多分私は不可能を試みています。
したがって、専門家への質問: これは許可されますか? それとも、リレーションのターゲットが埋め込みフィールドではない可能性がありますか (@EmbeddedId を除く)。
埋め込みをオーバーライドしてNormalizedNumber
、normaizedNumber を として定義できます@Id
か?