8.9 Hibernate-拥有实体实例不再引用具有cascade =“ all-delete-orphan”的集合 | Java Debug 笔记

811 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>

提问:Hibernate-拥有实体实例不再引用具有cascade =“ all-delete-orphan”的集合

尝试更新我的实体时遇到以下问题:

"A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance".

我有一个父实体,它有一些子实体的Set <...>。 当我尝试更新它时,我会获取所有要设置为此集合的引用并进行设置。

以下代码表示我的映射:

@OneToMany(mappedBy = "parentEntity", fetch = FetchType.EAGER)
@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })
public Set<ChildEntity> getChildren() {
    return this.children;
}

我尝试仅清理Set <..>:但是没有成功。

回答1:

检查要为子类实体分配内容的所有地方。 您引用的链接清楚地指出了创建新的HashSet的过程,但是在您重新分配该HashSet时,您可能会遇到此错误。 例如:

public void setChildren(Set<SonEntity> aSet)
{
    this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
}

通常,您只想在构造函数中“新建”一次集合。 每当您想向列表中添加或删除某些内容时,都必须修改列表的内容,而不是分配新的列表。

要添加子节点:

public void addChild(SonEntity aSon)
{
    this.sonEntities.add(aSon);
}

删除子节点:

public void removeChild(SonEntity aSon)
{
    this.sonEntities.remove(aSon);
}

回答2:

这个方法

public void setChildren(Set<SonEntity> aSet) {
    this.sonEntities = aSet;
}

如果parentEntity已分离,则该方法有效,进而我们对其进行更新

但是,如果没有根据上下文分离实体(即,查找和更新操作在同一事务中),则以下方法有效。

public void setChildren(Set<SonEntity> aSet) {
    //this.sonEntities = aSet; //This will override the set that Hibernate is tracking.
    this.sonEntities.clear();
    if (aSet != null) {
        this.sonEntities.addAll(aSet);
    }
}