カスケードを正しく動作させるためにクラスに適切な注釈を付ける方法を理解しようとしています。Hibernate OneToManyのカスケード問題
ここでは単純な親子シナリオを示します。
子供:
@Entity
@Table(name = "testChild")
public class testChild implements Serializable {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true, nullable = false)
@JsonProperty
private String uuid;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="parent_uuid", nullable=false)
@Cascade(value={CascadeType.ALL})
@JsonIgnore
private testParent parent;
@Column(name = "name")
@JsonProperty
private String name;
public testChild (testParent parent, String name) {
this.uuid = UUID.randomUUID().toString();
this.name = name;
this.parent = parent;
}
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public testParent getParent() {
return this.parent;
}
public void setParent (testParent parent) {
this.parent = parent;
}
}
親:
@Entity
@Table(name = "testParent")
public class testParent implements Serializable {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true, nullable = false)
@JsonProperty
private String uuid; // This is the figure uuid:<number>
@Column(name = "name")
@JsonProperty
private String name;
@Column(name = "children")
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", orphanRemoval=true, cascade = javax.persistence.CascadeType.ALL)
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
@JsonProperty
private List <testChild> children;
public testParent (String name) {
this.uuid = UUID.randomUUID().toString();
this.name = name;
this.children = new ArrayList<>();
}
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public List <testChild> getChildren() {
return this.children;
}
public void setChildren (List <testChild> children) {
this.children = children;
}
public testChild addChild(String childname) {
testChild c = new testChild(this, childname);
this.children.add(c);
return c;
}
}
とテストコード:
testParent p = new testParent("Dan");
sid = p.getUuid();
testChild c1 = p.addChild("Dan jr.");
testChild c2 = p.addChild("Dannielle");
session.save(p);
私の問題は、それが代わりに(最初の)子へのアップデートが生じていますということです挿入物の:
DEBUG org.hibernate.SQL - insert into testParent (name, uuid) values (?, ?)
DEBUG org.hibernate.SQL - update testChild set name=?, parent_uuid=? where uuid=?
もちろん、これはエラーをスローします。 私は親クラスと子クラスの両方でCascadeのかなりの組み合わせを試しました。
私が明示的に "session.save(object)"を常時使用していることが唯一のことです。すなわち 親を作成する - 子を作成する - 保存する、 作成するchild2 - 保存する、 最後に親をもう一度保存します。
私は本当にHibernateに、上から下にすべてを保存するように指示する方法を知りたいと思います。
このサイトや他のサイトからさまざまな提案がありましたが、何も問題はありません。
しかし、私はすでにaddChildメソッドでそれをやっています。 – DanTheMan
@DanTheManが私の答えを編集しました。親オブジェクトは既定でその子として既存のリストを持つので、その参照を取得し、子オブジェクトを追加して、これらが関連しており、1対多の関係として「永続化」する必要があると言う必要があります。 また、お互いを「認識」するためには、その子にも親を設定する必要があります。これを試して、変更がどのような違いを見たかを確認する必要があります。 –
@DanTheManあなたは子供の親も同様に設定しましたか? –