[英]Spring JPA merge parent entity from new child entity
我搜索了SO並沒有為此找到合適的解決方案。 假設我有一個父實體:
@Entity
public class Parent {
@Id
@GeneratedValue
private int id;
@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
private List<Child> childList;
}
和子實體,它具有與父實體關聯的外鍵:
@Entity
public class Child {
@Id
@GeneratedValue
private int id;
@JoinColumn(name = "parentId")
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Parent parent;
}
我的場景有點特別。 子實體每小時生成一次,我需要將它們保存到數據庫中。 這些子對象可以具有相同的父對象,並且關聯父實體可能已經存在於數據庫中。 我的要求是保存所有這些子對象而不從entityManager中查詢托管父實體,如果父實體存在,則只需合並/更新現有實體。 如:
Child c = new Child();
// set some properties of child
Parent p = new Parent();
// set some properties from my data into the parent. The parent may already exists
child.setParent(p);
JpaRepo.saveAndFlush(child);// If parent already exists, merge with the existed parent object, otherwise, create new parent object.
顯然這不起作用。 當父實體不存在時,它將正確創建父實體並與之關聯。 但是如果父元素已經存在,它將拋出關於重復鍵的異常,如果我設置父元素的Id(使用虛擬值強制使其通過合並),它將拋出分離的實體對象的異常。
由於性能限制,我無法從數據庫加載父實體,因為它們太多了。 那么當主鍵違反時,有沒有辦法自動為JPA或數據庫合並對象?
我正在使用MySQL,是否可以使用ON DUPLICATE KEY UPDATE?
你想要實現的是一個有點棘手的工作人員。 如果延遲加載等不是一個選項(我更喜歡),我建議您創建另一個實體:
@Entity
@Table(name = "sameAsTheOriginal")
public class ChildSaveObject {
@Id
@GeneratedValue
private int id; //I think int will run out fast if there are a lot of objects but it is your choice. (Int max value: 2 147 483 647 is not that mutch) I prefer Long az id
@Column(name = "parentId")
private int parent; //note that You need to have the id of the parent object
//Other properties...
}
在此流程中,您必須檢查父對象是否存在,並使用ChildSaveObject將其他子項保存到該對象。
在大多數情況下,我並不喜歡一對多的映射,我認為它們只是很多問題的根源。 如果您更喜歡這種方式,我建議使用fetch = FetchType.LAZY並獲取父實體(這樣它就不會加載您不需要的所有子項)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.