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

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

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

谢谢!


当前回答

我使用@user2709454方法,但改进很小。

public class User {
    private Set<Role> roles;

    public void setRoles(Set<Role> roles) {
        if (this.roles == null) {
            this.roles = roles;
        } else if(this.roles != roles) { // not the same instance, in other case we can get ConcurrentModificationException from hibernate AbstractPersistentCollection
            this.roles.clear();
            if(roles != null){
                this.roles.addAll(roles);
            }
        }
    }
}

其他回答

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

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

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

当我们以孩子为最终选择时,问题就解决了。

我们不应该在构造函数和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");

这种方法太过打破休眠。

我通过这样做来固定:

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

parent.getChildren().clear();

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

parent.getChildren().addAll(children);

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