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

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

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

谢谢!


当前回答

在2021年和Spring Boot 2.5中,它帮助我在声明字段时立即初始化它:

@OneToMany(mappedBy="target",fetch= FetchType.EAGER,cascade = CascadeType.ALL, orphanRemoval = true)
private List<TargetEntity> targets = new ArrayList<>();

其他回答

我最近在重构一些代码时遇到了这个问题。原始的(正确的)代码是这样的:

public virtual IEnumerable<SubscriptionPurchase> Purchases => _purchases;
public virtual SubscriptionPurchase MostRecentPurchase => _purchases.OrderByDescending(p => p.PurchaseDateUtc).FirstOrDefault();

我尝试通过将. orderbydescent移动到. purchasing属性来更改代码。这个更改破坏了代码,并导致OP中的引用错误:

public virtual IEnumerable<SubscriptionPurchase> Purchases => _purchases.OrderByDescending(p => p.PurchaseDateUtc);
public virtual SubscriptionPurchase MostRecentPurchase => Purchases.FirstOrDefault();

直到试图保存包含. purchasing属性的父对象时,错误才显示出来。

正如对这个问题的其他回答所指出的那样,出现这个问题是因为集合正在重置(在我的例子中是在对. purchasing的每个访问上)。

我在用JSON post请求更新实体时遇到了这种情况。 当我在没有关于子节点数据的情况下更新实体时发生错误,即使没有子节点数据。 添加

"children": [],

向请求体解决了问题。

另一个原因可能是使用龙目岛。

@Builder -导致保存Collections.emptyList(),即使你说.myCollection(new ArrayList());

@Singular -忽略类级别的默认值,并保留字段为空,即使类字段声明为myCollection = new ArrayList()

我的2美分,刚刚花了2个小时在同样的东西上:)

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

有一个类似的bug: https://hibernate.atlassian.net/browse/HHH-9940。

以及复制它的代码:https://github.com/abenneke/sandbox/tree/master/hibernate-null-collection/src/test

有2个可能的解决方案:

集合初始化为空集合(而不是null) orphanRemoval设置为false

例如- was:

@OneToMany(cascade = CascadeType.REMOVE,
        mappedBy = "jobEntity", orphanRemoval = true)
private List<JobExecutionEntity> jobExecutionEntities;

变成:

@OneToMany(cascade = CascadeType.REMOVE,
        mappedBy = "jobEntity")
private List<JobExecutionEntity> jobExecutionEntities;