hibernateは、POJOでListとして定義された子要素の実行順序を定義できますか? 複数の子を含む1つのParent
クラスがあるとします(Child1
、Child2
)。親と子の関連付けはOneToManyであり、リストとして定義されています。 親子の間に双方向の関係があります。 Child1
とChild2
の間にManyToOne関係もあります。 Child2
は、Child1
とManyToOne関係を持ちます。つまり、は、外部キー参照としてChild1
の主キーを含み、両方ともParent
とOneToMany関係を共有します。hibernateは子要素の保存順序を定義することができます
私たちはすべての親子関係を提供していると仮定して、今度は、hibernate sessionのmergeメソッドを呼び出しています。私たちがここで直面している問題は、Child1
とChild2
の間の関連付けが管理されていないことです。これは、 "指定された識別子の行がありません"というメッセージとともに、休止状態の例外を出します。このエラーは、休止状態の挿入親のために導出され、Child2
を挿入してからChild1
を挿入します。理想的には、Parent
,Child1
およびChild2
を挿入する必要があります。したがって、Child1
とChild2
の間の関連付けを管理できます。
理想的には、クラスはセッションファクトリで定義されたとおりにフェッチされるか、hibernate.cfg.xmlファイルで定義されます。ここでは、XMLでクラスを定義する順序を変更しようとしました。しかし、それは同じ結果をもたらします。
さらに、に関連付けられたChild1
の外部キー参照も削除しました。しかし、休止状態は自動的に関係を管理し、うまくいきません。
public class Parent{
private List<Child1> child1;
private List<Child2> child2;
public Parent(){
child1 = Collectionz.newArrayList();
child2 = Collectionz.newArrayList();
}
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true)
@Fetch(FetchMode.SUBSELECT)
public List<Child1> getChild1() {
return child1;
}
public void setChild1(List<Child1> child1) {
this.child1 = child1;
}
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true)
@Fetch(FetchMode.SUBSELECT)
public List<Child2> getChild2() {
return child2;
}
public void setChildren2(List<Child2> child2) {
this.child2 = child2;
}
}
public class Child1{
private Parent parent;
private Set<Child2> child2;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="PARENT_ID")
public PkgData getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
@OneToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY,mappedBy="child1")
@Fetch(FetchMode.SUBSELECT)
public Set<Child2> getChild2() {
return child2;
}
public void setChild2(Set<Child2> child2) {
this.child2 = child2;
}
}
public class child2{
private Parent parent;
private Child1 child1;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="PARENT_ID")
public PkgData getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="CHILD_1_ID")
public Child1 getChild1() {
return child1;
}
public void setChild1(Child1 child1) {
this.child1 = child1;
}
}
問題は、マージメソッドです。マージを使用するとHIbernateはうまく動作しません。 Hibernateは、分離されたエンティティを扱うとき、実際にはうまく動作しません。つまり、この機能があり、多くの単純な状況で役に立ちます。しかし、それは本当に揺れません。私たちはこのプロジェクトでもこの問題を抱えていました。それから、すべてをDTOを使用するように変更しました。すべてが今よりはるかにスムーズに動作します。 –
はい、私の考えではDTOも便利です。あなたのコアロジックはドメインを表す必要があり、クライアント、すなわちウェブには、ドメインと比較して見た目が異なる静かなデータが必要な場合は、データ転送オブジェクトを使用して状況を処理します。 –