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

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

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

谢谢!


当前回答

我的Spring Boot完全不同! 对我来说,这不是由于设置收集属性。

在我的测试中,我试图创建一个实体,并为另一个未使用的集合得到这个错误!

经过这么多的尝试,我只是在测试方法上添加了一个@Transactional,它解决了这个问题。但不要忘记原因。

其他回答

具有关系类型:


当集合在hasMany中声明时,不要尝试实例化它,只需添加和删除对象。

class Parent {
    static hasMany = [childs:Child]
}

使用关系类型:


但是集合只有在声明为属性(使用关系)并且没有在声明中初始化时才可能为空。

class Parent {
    List<Child> childs = []
}

这与之前的答案相反,我有完全相同的错误:“级联=“all-delete-orphan”的集合不再引用....”,当我的setter函数看起来像这样:

public void setTaxCalculationRules(Set<TaxCalculationRule> taxCalculationRules_) {
    if( this.taxCalculationRules == null ) {
        this.taxCalculationRules = taxCalculationRules_;
    } else {
        this.taxCalculationRules.retainAll(taxCalculationRules_);
        this.taxCalculationRules.addAll(taxCalculationRules_);
    }
}

然后当我把它改成简单的版本时,它就消失了:

public void setTaxCalculationRules(Set<TaxCalculationRule> taxCalculationRules_) {
    this.taxCalculationRules = taxCalculationRules_;
}

(hibernate版本-尝试了5.4.10和4.3.11。在回到setter中的简单赋值之前,花了几天时间尝试各种解决方案。现在很困惑为什么会这样。)

我在尝试使用TreeSet时遇到了这个问题。我用TreeSet初始化了oneToMany

@OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval=true)
@OrderBy("id")
private Set<WizardAnswer> answers = new TreeSet<WizardAnswer>();

但是,这将带来上述问题中所描述的错误。看起来hibernate支持SortedSet如果你把上面的行改成

@OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, orphanRemoval=true)
@OrderBy("id")
private SortedSet<WizardAnswer> answers;

它像魔法一样起作用:) 更多关于hibernate SortedSet的信息可以在这里

我通过这样做来固定:

1. 清除现有的子列表,以便从数据库中删除它们

parent.getChildren().clear();

2. 将上面创建的新子列表添加到现有列表中

parent.getChildren().addAll(children);

希望这篇文章能帮助你解决这个错误

而不是分配新的集合

public void setChildren(Set<ChildEntity> children) {
    this.children = children;
}

将所有元素替换为

public void setChildren(Set<ChildEntity> children) {
    Collections.replaceAll(this.children,children);
}