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

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

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

谢谢!


当前回答

下面的解决方案对我很有效

//Parent class
@OneToMany(mappedBy = 'parent', 
           cascade= CascadeType.ALL, orphanRemoval = true)
@OrderBy(value="ordinal ASC")
List<Child> children = new ArrayList<>()

//Updated setter of children 
public void setChildren(List<Children> children) {
    this.children.addAll(children);
    for (Children child: children)
        child.setParent(this);
}


//Child class
@ManyToOne
@JoinColumn(name="Parent_ID")
private Parent parent;

其他回答

我也犯了同样的错误。我的问题是,保存实体后映射的集合仍然为空,当试图更新实体时抛出异常。对我有帮助的是:保存实体,然后进行刷新(集合不再为空),然后执行更新。也许用new ArrayList()来初始化集合也会有帮助。

具有关系类型:


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

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

使用关系类型:


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

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

当我在我的父实体中使用这些注释时,我面临着类似的问题:

@Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN })

错误地,我试图在数据库中保存一个空父对象,并正确设置我的实体对象的值解决了我的错误。所以,做检查,如果你是愚蠢的设置错误的值或试图在数据库中保存一个空对象。

我有同样的问题,但它是当集合为空。只有在Set集合中,在List中工作正常。您可以尝试使用hibernate注释@LazyCollection(LazyCollectionOption.FALSE)而不是JPA注释fetch = FetchType.EAGER。

我的解决方案: 这是我的配置和工作良好

@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private Set<Barcode> barcodes;

@OneToMany(mappedBy = "format", cascade = CascadeType.ALL, orphanRemoval = true)
@LazyCollection(LazyCollectionOption.FALSE)
private List<FormatAdditional> additionals;

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