gpt4 book ai didi

jpa-2.0 - 删除子项时,JPA 关系不会更新

转载 作者:行者123 更新时间:2023-12-02 16:53:15 25 4
gpt4 key购买 nike

假设以下场景:

@Entity
public class A {
@OneToMany(mappedBy = "a", cascade = CascadeType.ALL)
private List<B> bList;
}

@Entity
public class B {
@ManyToOne()
@JoinColumn(name = "a_id", referencedColumnName = "id")
private A a;

@ManyToOne()
@JoinColumn(name = "c_id", referencedColumnName = "id")
private C c;
}

@Entity
public class C {
@OneToMany(mappedBy="c", cascade=CascadeType.ALL, orphanRemoval=true)
@CascadeOnDelete // eclipselink specific optimization annotation
private List<B> bList;
}

换句话说:对象A和对象C都包含多个B对象。

当我删除一个 C 对象时(从技术上讲,我正在更新一个包含多个 C 对象并使用孤立删除的对象),我希望删除所有引用的 B 对象,这可以按当前注释的预期工作。然而,实体管理器似乎不明白位于其缓存中的对象 A 现在已经丢失了一些子对象。如果我有一个 A 的实例,我当然必须手动更新它的 bList,或者执行一个新的查询来更新它,但即使是新获取的 A 对象仍然是过时的。重申一下:

  • C 对象已删除。
  • 删除通过 orphanRemoval 级联到 B 对象。
  • 实体管理器中缓存的 A 对象中的 bList未更新
  • 手动清除实体管理器缓存可使其检索正确更新的对象。

如何解决这个问题?我希望实体管理器自动更新其持久性上下文,或者在 @JoinColumn 上提供级联注释,但这里似乎都不是这种情况。

编辑:问题似乎在于对象 C 的 bList 在更新对象 A 的 bList 时未更新(因此无法级联更改)。但我不知道为什么......仍然请注意,我正在谈论持久性上下文而不是实例化对象。

最佳答案

JPA 不会为您维护关系,应用程序必须维护它们。这意味着当您删除一个实体时,应用程序负责清除对该实体的任何引用。当它是外键关系时,这一点很明显,因为如果不这样做,数据库约束通常会导致异常。在反向引用的情况下,虽然关系没有严格的数据库约束,但用户通常会错误地认为 JPA 会处理它 - 导致缓存损坏。

处理它的方法是删除对 C 和 B 实体的任何引用。在您的对象模型中,这意味着修复 A 的 bList 以删除 B。我已经看到这是通过实体删除事件或在应用程序代码中处理的。由于在这种情况下,A 没有外键,因此您还可以在删除发生后(即刷新或提交后)从数据库中刷新受影响的 A 实体。

关于jpa-2.0 - 删除子项时,JPA 关系不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5792712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com