当前位置: 首页 > 知识库问答 >
问题:

在JPA中删除子项时保持实体关系同步

夏侯昆琦
2023-03-14

我知道你需要保持有关系的实体同步,也就是说,当你从一个父实体中移除一个子实体时,你也应该在子实体中将父实体的属性设置为空。在我的示例中,我有以下父实体:

public class Parent {
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Child> children;
}

孩子:

public class Child {
    @ManyToOne(optional = false)
    private Parent parent;

    public void setParent(Parent parent) {
        this.parent = parent;
    }
}

从父级中删除子级的代码如下(在此示例中,父级可以多次在其列表中具有相同的子级):

public void removeChild(Child child) {
    List<Child> childrenToRemove = this.children.stream()
        .filter(c -> c.equals(child))
        .collect(Collectors.toList());
    childrenToRemove.forEach(child -> child.setParent(null));
    this.children.removeAll(childrenToRemove);
}

我首先将每个子级的<code>Parent</code>设置为NULL,然后将它们从集合中删除。这将使实体保持同步。我还可以将removeChild代码更改为以下内容:

public void removeChild(Child child) {
    this.children.removeIf(c -> c.equals(child));
}

当然,在这种情况下,实体不会保持同步,因为每个实体仍然具有对父级的引用。为了解决这个问题,我可以将以下内容添加到实体:

@PreRemove
public void preRemove() {
    this.parent = null;
}

我现在的问题是,如果Child实体也保存在不同父实体的列表中,例如,实体AnotherParent也保存了Child的列表,那么我是否也应该添加这个。anotherParent=null到上面定义的@PreRemove方法?如果Child与其他实体具有单向关系(即,另一方不保留Child实体的列表,是否应将其设置为空?)。

共有1个答案

盖向荣
2023-03-14

您应该保持双向关联同步,以便实体状态转换可以传播并避免代码中难以跟踪的错误。

我现在的问题是,如果子实体也保存在不同父实体的列表中,例如实体 OtherParent 也保留子实体列表,那么我是否也应该将 this.otherParent = null 添加到上面定义的@PreRemove方法中?

如果当前运行的持久性上下文中没有加载< code>AnotherParent实体,则不必这样做,因为父端集合不存在于内存中。

如果孩子与其他实体有单向关系(即另一方没有保留孩子实体的列表,应该将它们设置为null吗?)。

如果不这样做,将获得 ConstraintVirelationException,因为单向关联更像是多对多而不是一对多。

 类似资料:
  • 我是Spring BootJPA的新手,正在努力找出多个实体之间的关系。 我有一个用户实体、一个产品实体和一个评论实体。一个用户有很多评论。一个产品有很多评论。评论有一个产品和一个用户。 目前,我正在为用户使用一对多的关系 我的问题: 如何在不删除产品实体和用户实体的情况下删除审阅实体? 我应该使用哪种级联类型? 用户实体: 产品实体: 审查实体: 用户控制器: 用户服务: 简单运行: 我认为我不

  • 我的实体更新有问题。如你所见,我有三个实体。 包含类中的列表。 包含类中的列表。 从我的SQL语句中可以看到,字段和是唯一的。我的表中只允许该组合的一行。 当我用类的新列表更新父实体()时,我希望Hibernate删除旧列表本身并创建新实体。一个一个地更新孩子是有点困难的。这就是为什么我要直接删除所有相关的孩子。 当我更新并为其提供包含具有唯一名称的和(数据库中已存在的实体)组合的列表时,我会出现

  • 问题内容: 我有两个分别以双向一对多关系存在的实体类 A 和 B。 A.java: B.java 在一个简单的控制台应用程序中,我从数据库中获取了特定的 A 行,并尝试删除其详细信息 B 行(随机),但是 JPA / Hibernate* 不仅删除了该行-甚至没有向该行发出任何 DELETE 语句。数据库。删除 B 行的唯一方法是从 A.java 的集合( LinkedHashSet )中删除相应

  • 我在JPA中定义了两个实体:Employee和Skill。 在这些实体之间定义了relationship@ManyTomany。 现在我有这样的问题:如果我删除技能实体使用实体管理器。它移除OK。但是在@jointable中,在数据库employee_skill中,仍然存在与这个被删除的实体(其id)的关联。 我不想在移除技能时移除员工,所以所有的级联移除或孤立移除在这里都不有用。 我考虑了为什么

  • 删除父实体时,我还想删除关联的子实体(从数据库中)。我试图在删除时使用级联,如下所示,但我一定做错了什么。 当对父实体对象调用删除时,我收到错误消息:“该实体仍在数据库的其他地方引用”。我可以确认该实体在数据库的其他地方引用的唯一地方是在下面的两个表中(如果我手动从数据库中删除子行,对父实体对象的删除调用工作正常)。在过去的9个小时里,我一直在阅读实体对象并尝试不同的东西。我做错了什么? 这是我的

  • 我的实体。ValidationStep与documentDetail有一对一的关系,documentDetail与documentValidations有一个完全的关系 我的删除查询 父ValidationStep被删除,但是docDetail和documentValidations仍然在数据库中。