用例:我們有一個-多個雙向關系,我們將收到更新為父級的請求,其中包含正在修改或未修改的子項。技術棧彈簧靴 2.0.2彈簧數據 Jpa示例代碼:父類實體:package com.example.demo.model;import java.util.HashSet;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToMany;import org.hibernate.annotations.DynamicInsert;import org.hibernate.annotations.DynamicUpdate;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;@Getter@Setter@NoArgsConstructor@DynamicInsert@DynamicUpdate@Entitypublic class Parent { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String a; private String b; @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent") private Set<Child> childs = new HashSet<>(); public void addChild(Child child) { childs.add(child); child.setParent(this); } public void removeChild(Child child) { childs.remove(child); child.setParent(null); } public void setChilds( Set<Child> childrens) { if (this.childs == null) { this.childs = childrens; } else { this.childs.retainAll(childrens); this.childs.addAll(childrens); } }}通過上面的代碼,無法為子實體4設置父id,如果我們打印SQL日志,我們可以觀察到id為1的子被刪除,而id為3的子被插入,這是預期的。作為一種解決方法,我正在迭代所有子條目,如果未設置父條目,則手動設置。我不想要這個額外的更新聲明。嘗試了其他方法,使用同步的 removeChild 方法刪除所有子條目,然后使用同步的 addChild 方法一一添加剩余的條目。這導致唯一約束失敗異常。需要什么? 執行時在插入語句中設置父級而不是解決方法。
1 回答

慕妹3146593
TA貢獻1820條經驗 獲得超9個贊
問題來自這部分:
Set<Child> childrens = new HashSet<>();
childrens.add(c3);
childrens.add(c4);
retrievedParent.setChilds(childrens);
您永遠不需要重寫托管集合。
現在,根據您的設計:
如果我們知道刪除了 c1 并添加了 c3,我們可以使用 Parent 中編寫的同步方法。
因為我們不知道哪些被刪除,哪些被添加,因為我們不會從請求中獲取 id,將它們直接傳遞給 set 以讓 hibernate 將其處理為 equals 并且 Hashcode 已經寫入。
如果客戶端向您發送了一組條目,則您需要自己進行匹配,這意味著您需要:
添加新元素
刪除不再需要的元素
更新現有的
添加回答
舉報
0/150
提交
取消