JPA(Provider:Hibernate)で動作するために単方向の一対一の関係を取得しようとするのは非常に困難です。私の意見では、あまりにも面倒ではないはずですが、明らかにJPA/Hibernateはそれに同意しません;-)共有プライマリキーを使用したJPA/Hibernate単方向1対1マッピング
問題は、私が変更できないレガシースキーマと、このスキーマが共有プライマリ同時に2つのエンティティ間のキーであり、同時に1つのエンティティに対する外部キーである。
私は簡単なテストケースを作成し、次のよう
DBに見えます:
CREATE TABLE PARENT (PARENT_ID Number primary key, Message varchar2(50));
CREATE TABLE CHILD (CHILD_ID Number primary key, Message varchar2(50),
CONSTRAINT FK_PARENT_ID FOREIGN KEY (CHILD_ID)REFERENCES PARENT (PARENT_ID));
CREATE SEQUENCE SEQ_PK_PARENT START WITH 1 INCREMENT BY 1 ORDER;
次のように親(1対1の=所有している側)になります。
@Entity
@Table(name = "PARENT")
public class Parent implements java.io.Serializable {
private Long parentId;
private String message;
private Child child;
@Id
@Column(name = "PARENT_ID", unique = true, nullable = false, precision = 22, scale = 0)
@SequenceGenerator(name="pk_sequence", sequenceName="SEQ_PK_PARENT")
@GeneratedValue(generator="pk_sequence", strategy=GenerationType.SEQUENCE)
public Long getParentId() {
return this.parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
@Column(name = "MESSAGE", length = 50)
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
@OneToOne (cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(name="PARENT_ID", referencedColumnName="CHILD_ID")
public Child getTestOneToOneChild() {
return this.child;
}
public void setTestOneToOneChild(Child child) {
this.child = child;
}
}
子供:
@Entity
@Table(name = "TEST_ONE_TO_ONE_CHILD", schema = "EXTUSER")
public class Child implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Long childId;
private String message;
public Child() {
}
public Child(String message) {
this.message = message;
}
@Id
@Column(name = "CHILD_ID")
public Long getChildId() {
return this.childId;
}
public void setChildId(Long childId) {
this.childId = childId;
}
@Column(name = "MESSAGE", length = 50)
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
私は、JPAが子供のためにIDを割り当てる方法を知らないという問題を完全に見ています。しかし私はまた、Hibernatesの "foreign"キージェネレータを使用してみました。これは成功しませんでした。なぜなら、それは望ましくない子から親への逆参照を必要とするからです。 この問題はあまりにも珍しいようではないので、私はここで何が欠けていますか?解決策はありますか?純粋なJPAが解決策を提供しない場合、私はまた、休止状態の拡張を使用することもできます。正しい動作のための
私の期待は次のようになります。 私は付属の子どもと親を持続しようとした場合:
- は親
- を持続し、親にそれを設定し、シーケンスからIDを取得します私は、「スタンドアロン」を持続しようとした場合、子
- のセット親のIDは子
を持続します子供entityManager.persist(aChild))私はRuntimeExceptionを期待します。
ご協力いただきありがとうございます。
私はそれを試したことはありませんが、getterに注釈を付けると動作するかもしれません。これは、Hibernateにsettersを使ってPOJOを設定するよう指示します。 setParentId()メソッドとsetChild()メソッドで子IDを設定しようとする可能性があります(まだない場合)。 –
いいえ、動作しません:IdentifierGenerationException:save()を呼び出す前にこのクラスのIDを手動で割り当てる必要があります – Korgen
どのバージョンのHibernateを使用しますか? – axtavt