3 つの Java クラス (Person から Heart、および Person から Liver) のオブジェクト間の単方向の 1 対 1 の関係が必要です。オブジェクトが同じ PK を共有するようにします。つまり、すべての人が対応する心臓と肝臓を持っています。それぞれにたくさんのフィールドがあるため、3 つのテーブルを 1 つにマージしたくありません。これが私のコードです(主にこの質問に対する受け入れられた回答に基づいています):
@Entity
public class Person {
public long personId;
private String name;
public Heart heart;
public Liver liver;
// other fields
@Id
@GeneratedValue
public long getPersonId() {return personId;}
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {return heart;}
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Liver getLiver() {return liver;}
// other getters and setters and constructors
}
@Entity
public class Heart {
private long heartId;
private int bpm;
private Person person;
// other fields
@Id
@GenericGenerator(
name = "generator",
strategy = "foreign",
parameters = @Parameter(name = "property", value = "person")
)
@GeneratedValue(generator = "generator")
public long getHeartId() {return heardId;}
@OneToOne(mappedBy="heart")
@PrimaryKeyJoinColumn
public Person getPerson() {return person;}
// other getters and setters and constructors
}
@Entity
public class Liver {
private long liverId;
private boolean healthy;
private Person person;
// other fields
// the rest uses the same hibernate annotation as Heart
}
セッションをセットアップし、次のことを行います。
Person jack = new Person();
jack.setName("jack");
Heart heart = new Heart();
heart.setBpm(80);
Liver liver = new Liver();
liver.setHealthy(true);
次に、人物オブジェクトを臓器にリンクして保存すると、エラーが発生します (注: Person と Heart などの 2 つのクラスを使用したときと同じ動作が得られました)。
jack.setHeart(heart);
jack.setLiver(liver);
session.save(jack);
org.hibernate.id.IdentifierGenerationException: null の 1 対 1 のプロパティから ID を割り当てようとしました: person
ただし、関係を両方の方法で設定すると機能します。
jack.setHeart(heart);
heart.setPerson(jack);
jack.setLiver(liver);
liver.setPerson(jack);
session.save(jack);
しかし、確かにこれは一方向の関係には必要ないのでしょうか?
乾杯
ps。奇妙なことに、Person と Heart などの 2 つのクラスを使用し、リンクを別の方法で設定すると、機能する (両方のオブジェクトが DB に保存される) ことに気付きます。
heart.setPerson(jack);
session.save(heart);
なぜこれが機能するのかわかりません (Person は親オブジェクトであり、独自の PK を自動生成し、他のオブジェクトがそれを使用するため、セットアップする必要があるのはそれだけです) が、とにかく私には理解できませんこの作業方法を私の3クラスの状況に適用する方法...