如何解决将现有子实体映射到新父实体时传递给持久化的分离实体
我有两个实体,如下所示。
// Parent entity
class Parent {
@OnetoMany(mappedBy = "parent",orphanRemove=true,cascade=CascadeType.ALL)
Set<Child> children;
}
// Child entity
class Child {
@ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST})
Parent parent;
}
我已经有一个 Parent
对象,它有两个 Child
对象,我想将一个 Child
对象从当前的 Parent
移动到新的 Parent
。
@Transactional
public void mapChildToNewParent() {
// Get existing child and remove it from existing parent
Parent existingParent = parentRepo.findById(1L);
Child existingChild = existingParent.getChildren().iterator().next();
existingParent.remove(existingChild);
// Create new parent and add existingChild in it
Parent newParent = new Parent();
Set<Child> childrens = new HashSet<Child>();
childrens.add(existingChild);
newParent.setChildren(childrens)
// Save modified parent entities
parentRepo.save(existingParent);
parentRepo.save(newParent);
}
现在当我这样做时,save 方法抛出 detached entity passed to persist: Child
解决方法
您在代码中遗漏了一个基本步骤:您需要更新关联的拥有方。缺少可能会导致此类异常或阻止 Hibernate 对数据库执行任何更新。
并且您可能需要仔细检查您的级联操作。在这篇文章的末尾有更多关于这个的信息。
免责声明:我无法在示例项目中重现错误消息。 Hibernate 没有出现错误,而是悄悄地从数据库中删除了子记录。但这可能是一个细节,取决于 Hibernate 版本和/或周围的代码。
管理双向关联
让我们从最重要的部分开始:您对双向关联进行了建模。当您在业务代码中使用它时,您总是需要更新双方。
如果您想更深入地研究关联映射,我建议您学习我的 best association mapping articles。
在您的示例中,缺少 child.setParent(newParent)
方法的调用:
@Transactional
public void mapChildToNewParent() {
// Get existing child and remove it from existing parent
Parent existingParent = parentRepo.findById(1L);
Child existingChild = existingParent.getChildren().iterator().next();
existingParent.remove(existingChild);
// Create new parent and add existingChild in it
Parent newParent = new Parent();
Set<Child> childrens = new HashSet<Child>();
childrens.add(existingChild);
newParent.setChildren(childrens)
child.setParent(existingChild);
// Save modified parent entities
parentRepo.save(existingParent);
parentRepo.save(newParent);
}
使用级联和 orphanRemoval
您在映射中使用了级联和 orphanRemoval。这些应该仅用于子级依赖父级的纯父子关联。在这些情况下,在关联的两端都有级联定义是不常见的。您应该仔细检查是否需要 Child.parent
属性的级联定义,以及它是否提供了预期的结果。
如果您的父级有很多子级,级联删除操作可能会导致 performance issues。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。