我有以下的自表映射:休眠「刪除被persist實體」的問題與Cascade.DELETE_ORPHAN和父/子關係
public class Node implements {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "IDFATHER", referencedColumnName = "ID")
private Node father;
@OneToMany(mappedBy = "father", fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@Cascade(value =
{
CascadeType.ALL,
CascadeType.DELETE_ORPHAN
})
private List<Node> children;
基本上它是使用同一個表經典的父/子節點樹,IDFATHER列指向父節點的ID。
我已經實現在樹上的一些基本操作:
- 批量刪除:刪除選定的節點+所有子女
- 單刪除:只刪除選定的節點,其所有的孩子重新重視其父
- 等...
要實現操作2)單刪除:
// father of the node to be deleted
Node father = deletedNode.getFather();
if (deletedNode.getChildCount() != 0)
{
List<eNode> tempChildren = new ArrayList<Node>();
// put all children of deleted node in a temp list because the
// new FOR loop doesn't allow concurrent modification while looping
for (Node child : deletedNode.getChildren())
{
tempChildren.add(child);
}
for (Node child : tempChildren)
{
// re-attach first all the children to the father
father.getChildren().add(child);
child.setFather(father);
// remove all the children from the deleted node list
deletedNode.getChildren().remove(child);
// remove the deleted node from the father children' list
father.getChildren().remove(deletedNode);
}
}
this.nodeDAO.flush();
我得到異常
javax.persistence.EntityNotFoundException:刪除的實體傳遞給 堅持
據我瞭解,根據官方的文檔,當你刪除一個實體, Cascade.ALL
,刪除級聯到它的子級。然而,在這種特殊情況下,所有的孩子都被重新綁在父親身上,所以他們不應該被刪除...
當我刪除Cascade.DELETE_ORPHAN
,它的工作原理。從邏輯上講,通過將孩子重新附加到父親身上,他們不再是孤兒,所以Cascade.DELETE_ORPHAN
應該不是很重要。
在這個問題上的任何線索?
謝謝你的回覆瑞恩。所以,如果我明白DELETE_ORPHAN的語義沒有考慮到一個孩子有一個新的父親的可能性... – doanduyhai
不是我曾經注意過。回想起來,這看起來很奇特,但這並不是你經常會遇到的情況。我想你的選擇是要麼自己管理刪除,要麼創建新的節點以移植到樹中,而不是重複使用舊節點。 –