私は既存のスキーマを使用していますが、変更したくないです。スキーマは、PersonテーブルとVitalStatsテーブルの間に1対1の関係があります。Personは主キーを持ち、VitalStatsはその主キーと外部キーの両方と同じフィールドをPersonに使用します。つまり、その値は対応するPKの値人の。
これらのレコードは外部プロセスによって作成され、私のJPAコードはVitalStatsを更新する必要はありません。私のオブジェクトモデルでは、PersonクラスにVitalStatsメンバーを含めたいのですが、
しようとすると
@Entity
public class Person{
private long id;
@Id
public long getId(){ return id; }
private VitalStats vs;
@OneToOne(mappedBy = “person”)
public VitalStats getVs() { return vs; }
}
@Entity
public class VitalStats{
private Person person;
@OneToOne
public Person getPerson() { return person; }
}
VitalStatsには@Idが欠けているという問題がありますが、@ Entityでは機能しません。\
私が試してみると
@Id @OneToOne
public Person getPerson() { return person; }
@Idの問題は解決しますが、Personをシリアライズ可能にする必要があります。それに戻ります。
VitalStatsを@Embeddableにして、@ ElementCollectionを介してPersonに接続できますが、要素が1つしかないことを知っていても、コレクションとしてアクセスする必要があります。実行可能ですが、少し迷惑で少し混乱します。
では、PersonがSerializableを実装していると言っているのを防いでいるのはなぜですか?理由はありませんが、コード内のすべてのものがそこにあることが好きで、これに対するロジックが表示されないため、コードが読みにくくなります。
それまでは、VitalStatsのPersonフィールドを長いpersonIdに置き換え、そのVitalStatsの@Idを作成したので、@ OneToOneが機能するようになりました。
(私には)単純な問題のように思われるこれらの解決策はすべて少し不格好であるため、何かが足りないのか、誰かが少なくともSerializableである理由を説明できるのかどうか疑問に思っています。
TIA
共有主キーを使用して1対1の関連付けをマップするには、@PrimaryKeyJoinColumn
および@MapsId
注釈を使用します。
Hibernateリファレンスドキュメントの関連セクション:
PrimaryKeyJoinColumnアノテーションは、エンティティのプライマリキーが関連付けられたエンティティの外部キー値として使用されることを示しています。
MapsIdアノテーションは、Hibernateに別の関連付けられたエンティティから識別子をコピーするように要求します。 Hibernateの専門用語では、外部ジェネレーターとして知られていますが、JPAマッピングは読みやすく、推奨されています
Person.Java
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "person_id")
private Long id;
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private VitalStats vitalStats;
}
VitalStats.Java
@Entity
public class VitalStats
{
@Id @Column(name="vitalstats_id") Long id;
@MapsId
@OneToOne(mappedBy = "vitalStats")
@JoinColumn(name = "vitalstats_id") //same name as id @Column
private Person person;
private String stats;
}
個人データベーステーブル
CREATE TABLE person (
person_id bigint(20) NOT NULL auto_increment,
name varchar(255) default NULL,
PRIMARY KEY (`person_id`)
)
VitalStatsデータベーステーブル
CREATE TABLE vitalstats
(
vitalstats_id bigint(20) NOT NULL,
stats varchar(255) default NULL,
PRIMARY KEY (`vitalstats_id`)
)
私の場合、これはトリックを作りました:
親クラス:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/** auto generated id (primary key) */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;
/** user settings */
@OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
private Setting setting;
}
子クラス:
public class Setting implements Serializable {
private static final long serialVersionUID = 1L;
/** setting id = user id */
@Id
@Column(unique = true, nullable = false)
private Long id;
/** user with this associated settings */
@MapsId
@OneToOne
@JoinColumn(name = "id")
private User user;
}