2017-04-13 6 views
0

Springデータを使用して、以下のエンティティをデータベースに格納する際に問題があります。 OneToOne関係は、これらの2つの間で使用されます。これは、parentObjectが明示的にchildObjectに設定されている場合にのみ機能します。私はその子オブジェクトが親を全く持たないことを望むので、これは素晴らしい解決策ではありません。それは可能かどうか? 非常に関連した質問がしかし共有IDを持つOneToOneの関係は、子が親を知ることが必要です

@Entity 
@Table(name = "parent_object") 
public class ParentObject { 
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "id", unique = true, nullable = false) 
private Long id; 

@Column(name = "age") 
private Long age; 

@OneToOne(cascade = CascadeType.ALL, mappedBy = "parentObject") 
private ChildObject childObject; 

public ParentObject() { 
} 

public ParentObject(Long age, ChildObject childObject) { 
    this.age = age; 
    this.childObject = childObject; 
} 

public Long getId() { 
    return id; 
} 

public Long getAge() { 
    return age; 
} 

public ChildObject getChildObject() { 
    return childObject; 
} 

public void setChildObject(ChildObject childObject) { 
    this.childObject = childObject; 
} 
} 

@Entity 
@Table(name = "child_object") 
public class ChildObject { 
@Id 
@Column(name = "child_id", unique = true, nullable = false) 
private Long id; 

@MapsId 
@OneToOne 
@JoinColumn(name = "child_id") 
private ParentObject parentObject; 

@Column(name = "name") 
private String name; 

public ChildObject() { 
} 

public ChildObject(String name) { 
    this.name = name; 
} 

public Long getId() { 
    return id; 
} 

public ParentObject getParentObject() { 
    return parentObject; 
} 

public String getName() { 
    return name; 
} 

public void setParentObject(ParentObject parentObject) { 
    this.parentObject = parentObject; 
} 
} 

hereを掲載して、私は本当にChildObjectにparentObjectを設定することが好きではない:

ChildObject childObject = new ChildObject("name"); 
ParentObject parentObject = new ParentObject(12L, childObject); 
childObject.setParentObject(parentObject); 

がこのIDを共有しているための唯一の方法ですか? parentObjectが明示的に設定されていない場合は、次のエラーがスローされます。

Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [test.ChildObject.parentObject] 
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:83) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] 
+0

ChildObjectクラスからparentObjectフィールドを削除し、@JoinColumn(name = "child_id")private ChildObject childObjectをparentObjectに追加してmappedByを削除しました。 原因:org.hibernate.id.IdentifierGenerationException:save()を呼び出す前に、このクラスのIDを手動で割り当てる必要があります。 –

答えて

1

問題の呼び出しが必要とされないように、あなたは簡単に操作をカプセル化することができますを確かに、あなたは常にあなたのインメモリモデルは、一貫した状態に常にあることには、この作業を行う必要があります。

public class ParentObject{ 

    public ParentObject(Long age, ChildObject childObject) { 
     this.age = age; 
     this.childObject = childObject; 

     childObject.setParentObject(this); 
    } 

    public void setChildObject(ChildObject childObject) { 
     this.childObject = childObject; 
     childObject.setParentObject(this); 
    } 
} 

さて、あなたのDomain Model APIのクライアントは、後方参照フォームChild to Parentについて何も知る必要はありません。

1

あなたは(あなたが両側のOneToOneアノテーションを持っている)双方向の関係を持っているので、あなたが他の側には関係の各側面の参照を保持する必要がありますあなたが好きではない場合は、一方の側から参照とマッピングを削除することによって、関係を単方向関係にすることができます。

+0

目的は単方向リレーションシップを取得することです。子クラス@Id @Column(name = "child_id"、unique = true、nullable = false) プライベートLong ID。 親クラスで@OneToOne(orphanRemoval = true、カスケード= CascadeType.ALL) @JoinColumn(name = "child_id") private ChildObject childObject; しかし、エラーは次のように使用されています:org.hibernate.id.IdentifierGenerationException:このクラスのIDは、save()を呼び出す前に手動で割り当てる必要があります –

+0

リレーションが一方向である場合は、リレーションシップをParentObjectからChildObjectに一方向にすると、ChildObject内のParentObject参照を削除する必要があります –

関連する問題