0
我認爲這是相當常見的模式,當我們有一個集合的實體並希望通過前端進行更新時。休眠:通過DTO的值更新實體
class Parent {
long id;
List<Child> childs;
}
class Child {
long id;
String property;
}
class ParentDTO {
long id;
List<ChildDTO> childs;
}
class ChildDTO {
long id;
String property;
}
現在我有一個像
public void createOrUpdate(ParentDTO parentDTO) {
Parent parent;
if (parentDTO.id == 0L) {
parent = new Parent();
parent.childs = ChildDTO.convertToEntities(parentDTO.childs);
} else {
parent = em.find(Parent.class, parentDTO.id);
syncParent(parent, parentDTO);
}
em.saveOrUpdate(parent);
}
public static void syncParent(Parent parent, ParentDTO parentDTO) {
// this will cause issues due to setting session attached
// parent.childs collection to a new one
// parent.childs = ChildDTO.convertToEntities(parentDTO.childs);
// the better way is
parent.childs.clear();
parent.childs.addAll(ChildDTO.convertToEntities(parentDTO.childs);)
// however let's look at convert method
}
public static List<Child> convertToEntities(List<ChildDTO> childDTOs) {
//let's skip iteration
Child child = new Child();
child.id = childDTO.id;
child.property = childDTO.property;
// return childs
}
這裏的問題的方法是,如果我設置的ID從ChildDTO兒童試圖更新現有的兒童 - hibernate會拋出一個「獨立實體通過堅持「的例外。
我知道那個固定的方法有兩種:
- 不要設置一個ID,這樣孩子的將獲得新的ID每次都堅持時間
- 導線現有孩子的收集,並找到相應的childDTOs(具有相同的ID),然後複製值
如果您有更深的層次結構,第二種方法很麻煩。有沒有辦法做正確的事情,即當id設置爲Child時,hibernate會發現它實際上應該使用該id從Em重新加載Child(),並用新字段進行更新。
解決此問題的正確方法是什麼?