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

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

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

谢谢!


当前回答

这与之前的答案相反,我有完全相同的错误:“级联=“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中的简单赋值之前,花了几天时间尝试各种解决方案。现在很困惑为什么会这样。)

其他回答

加上我愚蠢的回答。我们正在使用Spring Data Rest。这是我们很正常的关系。这种模式在其他地方也被使用。

//Parent class
@OneToMany(mappedBy = 'parent', 
           cascade= CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
List<Child> children = new LinkedList<>()


//Child class
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = 'ParentID', updatable = false)
@JsonBackReference
Parent parent

对于我们创建的关系,总是打算通过它们自己的repo添加子节点。我还没有添加回购。我们的集成测试通过REST调用经历了实体的完整生命周期,因此事务将在请求之间关闭。没有子对象的repo意味着json将子对象作为主结构的一部分,而不是在_embedded中。对父进程的更新将导致问题。

小心

BeanUtils.copyProperties(newInsum, insumOld,"code");

这种方法太过打破休眠。

@OneToMany(mappedBy = 'parent', cascade= CascadeType.ALL, orphanRemoval = true)
List<Child> children = new ArrayList<>();

当我将子对象添加到现有的子对象列表中时,我遇到了相同的错误。

childService.saveOrUpdate(child);
parent.addToChildren(child);
parentService.saveOrUpdate(parent);

解决我问题的是:

child = childService.saveOrUpdate(child);

现在孩子复活了其他细节以及它工作得很好。

我在尝试使用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的信息可以在这里

方法:

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