为了账号安全,请及时绑定邮箱和手机立即绑定

Hibernate-拥有实体实例不再引用具有cascade =“ all-delete-orphan

Hibernate-拥有实体实例不再引用具有cascade =“ all-delete-orphan

弑天下 2019-11-25 15:38:43
尝试更新我的实体时遇到以下问题:"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 <..>:如何“可能”解决问题,但没有成功。如果您有任何想法,请告诉我。
查看完整描述

3 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

检查所有要为sonEntities分配内容的地方。您引用的链接清楚地指出了创建一个新的HashSet的过程,但是在您重新分配该HashSet时,您可能会遇到此错误。例如:


public void setChildren(Set<SonEntity> aSet)

{

    this.sonEntities = aSet; //This will override the set that Hibernate is tracking.

}

通常,您只想在构造函数中一次“新”集合。每当您想向列表中添加或删除某些内容时,都必须修改列表的内容,而不是分配新的列表。


要添加子代:


public void addChild(SonEntity aSon)

{

    this.sonEntities.add(aSon);

}

删除孩子:


public void removeChild(SonEntity aSon)

{

    this.sonEntities.remove(aSon);

}


查看完整回答
反对 回复 2019-11-25
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

方法:


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

    }

}


查看完整回答
反对 回复 2019-11-25
?
慕村225694

TA贡献1880条经验 获得超4个赞

当我在不同的地方阅读休眠而不喜欢您分配给集合的内容时,我认为最安全的做法显然是将其设置为最终状态,如下所示:


class User {

  private final Set<Role> roles = new HashSet<>();


public void setRoles(Set<Role> roles) {

  this.roles.retainAll(roles);

  this.roles.addAll(roles);

}

}

但是,这不起作用,并且会出现可怕的“不再引用”错误,在这种情况下,这实际上是很容易引起误解的。


事实证明,hibernate调用了setRoles方法,并且希望将其特殊的收集类安装在此处,并且不接受您的收集类。尽管阅读了有关在set方法中未分配给您的集合的所有警告,但这使我很困惑。


所以我改为:


public class User {

  private Set<Role> roles = null;


  public void setRoles(Set<Role> roles) {

  if (this.roles == null) {

    this.roles = roles;

  } else {

    this.roles.retainAll(roles);

   this.roles.addAll(roles);

  }

}

}

这样,在第一次调用时,hibernate将安装其特殊类,而在后续调用中,您可以自己使用该方法而不会破坏所有内容。如果您想将类用作Bean,则可能需要一个有效的setter,至少这似乎可行。


查看完整回答
反对 回复 2019-11-25
  • 3 回答
  • 0 关注
  • 2179 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信