【问题标题】:Why does JPA OneToOne (even OneToMany) have its orphanRemoval default to false为什么JPA OneToOne(甚至OneToMany)的orphanRemoval默认为false
【发布时间】:2021-03-07 22:59:57
【问题描述】:

为什么 JPA OneToOne(或者甚至是 OneToMany)的 orphanRemoval 默认为 false。

我的意思是,将删除操作强制到已从关系中删除的实体并默认将删除操作级联到这些实体并让用户选择不明确执行它不是更好吗?

如果只使用默认值,当前默认值为 false 的行为是否不会导致孤立条目(可能会成为僵尸记录)随着时间的推移可能导致数据库表膨胀?还是我在这里遗漏了什么?

谢谢

更新(2020 年 12 月 6 日): 我专门询问OneToOne 和OneToMany 是有原因的。至少在这两种情况下,据我了解,在大多数情况下,默认的删除行为是 most appropriate thing to do 而不是删除实际上是不推荐的,因此是这个问题。

更新了上一点的official oracle documentation 链接。同时引用以下部分以供快速参考,

当一对一或一对多关系的目标实体是 从关系中删除,通常需要级联 删除对目标实体的操作。此类目标实体是 被认为是“孤儿”,并且 orphanRemoval 属性可用于 指定应删除孤立实体。

【问题讨论】:

  • 再次感谢@Lokesh 提供有用的想法和时间,希望您有机会查看我的回复……请让我知道您的想法。另外,是否有人对此有任何意见和想法?

标签: java hibernate jpa spring-data-jpa hibernate-mapping


【解决方案1】:

如果 orphanRemoval 默认操作为真,那么它将在用户不知情的情况下删除关联的表记录。大多数开发人员通常会忽略级联操作的默认行为并最终删除关联的表数据。如果您已删除数据并且无法取回数据。想象在用户不知情的情况下删除数据有点可怕(在我看来)。

如果您忽略了 orphanRemoval 标志并将其保留为默认选项,则当前行为将允许您选择该选项。您可以选择清理孤立记录或保持原样。可以使用带有连接子句的简单删除查询来清理孤立记录。

在某些情况下,您可能需要孤立记录来追溯历史。例如 - 订单和产品信息。可以删除产品,但您不想删除关联的订单。

【讨论】:

  • 感谢您的回复@Lokesh。我专门询问OneToOne 和OneToMany 是有原因的。据我了解,在这两种情况下(至少),在大多数情况下,删除的默认行为是最合适的做法,实际上不推荐不删除,因此是问题所在。同样在产品和订单示例中,产品可能不会自然地与订单具有OneToMany 关联,我可以看到订单自然地与产品具有ManyToOne 关联,但主要是出于优化目的或在特定的双向定向查询需求
  • 同样在这一点上,“选择清理孤立记录还是保持原样”不会随着时间的推移导致速度缓慢、大小“泄漏”和性能问题?
猜你喜欢
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多