我有以下问题时,试图更新我的实体:

"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<..只有>,根据这个:如何“可能”解决问题,但它没有工作。

如果你有什么想法,请告诉我。

谢谢!


当前回答

实际上,我的问题是关于实体的equals和hashcode。遗留代码会带来很多问题,永远不要忘记检查它。我所做的只是保持删除孤立策略和正确的等号和hashcode。

其他回答

我唯一一次得到这个错误是当我试图将NULL传递到集合的setter时。为了防止这种情况,我的setter是这样的:

public void setSubmittedForms(Set<SubmittedFormEntity> submittedForms) {
    if(submittedForms == null) {
        this.submittedForms.clear();
    }
    else {
        this.submittedForms = submittedForms;
    }
}

@OneToMany(mappedBy = "entity_b", cascade = [CascadeType.]所有],orphanRemoval = true)

我也遇到了同样的错误。当我删除上面结构中的;"orphanRemoval = true"部分时,它工作了

方法:

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);
    }
}

当我设置parent时,拥有的实体实例不再引用级联= " all-delete-orphan "的集合。setChildren(新ArrayList < >())。当我改为parent.getChildren().clear()时,它解决了这个问题。

请查看更多详细信息:HibernateException - cascade="all-delete-orphan"的集合不再被所属实体实例引用。

检查所有你给sonEntities赋值的地方。您所引用的链接明确指出了创建一个新的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);
}