Hibernate JPA级联类型

3

我已经多次阅读了级联类型的定义,但是我仍然无法理解在特定情况下应该使用哪种。

Worker类和Task类之间存在@OneToMany关系,因此worker可以有多个任务,但每个Task只属于一个Worker

private List <Task> tasksWorker类中保存任务,而private Worker worker;Task类中的Worker对象

我卡在下面的?处,不知道应该使用哪种级联类型。

@OneToMany(targetEntity=Task.class, mappedBy="worker", cascade=CascadeType.?, fetch = FetchType.LAZY)

两个对象都应该独立存在,但我希望对Task对象的更改能够反映在Worker对象上,反之亦然

最终(如果我能让这个工作 :) ),我应该编写一个算法来匹配最佳工人,当新任务进入系统时,我想知道我是否正确。谢谢


"这两个对象应该相互独立存在,但我希望对任务对象的更改能够反映在工人对象上,反之亦然。" <- 你能具体说明一下你的意思吗?你是指如果修改了“任务-A”,那么与之关联的工人对象不应该链接到旧版本的“任务-A”吗?如果你只关心这一点,那么你根本不需要使用CascadeType(NONE)。 - user6073886
我建议您使用cascade=CascadeType.ALL并添加deleteOrphan=true。但是,如果您使用JPA 2/2.1 + Hibernate 5,则级联删除不会得到很好的管理,我建议您手动执行级联删除。 - Zorglube
1
@Zorglube,应该使用orphanRemoval而不是deleteOrphan。如果使用deleteOrphan,它将删除与另一侧没有关系的元素,这不是他想要的。 - cнŝdk
1
感谢 @chsdk 的指正。 - Zorglube
2个回答

4

在你的特定情况下,你想把一个实体的更改还原到另一侧,如果映射实体被删除,你不想将其删除,以回答你的两个要求:

这两个对象应该互相存在

在这种情况下,你不应使用 CascadeType.REMOVE 类型,因为它会在拥有实体被删除时删除与此设置相关的所有相关实体关联。

但我希望对 Task 对象的更改能够反映在 Worker

在这种情况下,使用 CascadeType.PERSISTCascadeType.MERGE 类型就足以反映两侧之间的更改,因为 CascadeType.PERSIST 包括 save()persist() 操作,而 CascadeType.MERGE 将处理 merge() 操作。

如果想要了解更多关于这个主题的细节,我建议阅读HowToDoInJava Hibernate JPA Cascade Types article,因为它简要地说明了所有这些情况。


1
谢谢,现在我明白了。 - Ulug Toprak
请注意,上面的链接文章轻率地混淆了“关系所有者”和“父母”的概念。 - diarmuid
我看不出这有什么混淆的地方,它只是使用“所有者”和“关系”的术语来说明。 - cнŝdk

3

这取决于您如何使用实体。

  • 如果您从未分离过您的实体,那么您不需要CascadeType.DETACH。如果您这样做了,那么您可能应该包含这个CascadeType
  • 当您将分离的工作者合并回持久化上下文时,您是否也希望其任务被合并?这不是一个容易的决定,但从您所说的情况来看,您可能不会在同一进程中修改工作者和任务,因此您可能不需要这个CascadeType
  • CascadeType.PERSIST通常是一个很好的选择,您不太可能出错。但像上面一样:您似乎没有在同一进程中创建工作者和新的任务。但如果您这样做了,请选择这个CascadeType
  • 从我所理解的情况来看,您绝对不想使用CascadeType.REMOVE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接