【问题标题】:Hibernate second level cache and ON DELETE CASCADE in database schema数据库模式中的休眠二级缓存和 ON DELETE CASCADE
【发布时间】:2025-12-21 10:05:16
【问题描述】:

我们的 Java 应用程序有大约 100 个类映射到数据库(SQL Server 或 MySQL)。我们使用 Hibernate 作为我们的 ORM(带有 XML 映射文件)。

我们在数据库模式中指定FOREIGN KEY 约束。我们的大多数FOREIGN KEY 约束也指定ON DELETE CASCADE

我们最近开始启用 Hibernate 二级缓存(用于流行的实体和集合)以缓解一些性能问题。

自从我们启用二级缓存后,性能得到了提升。然而,我们也开始遇到 ObjectNotFoundExceptions。

似乎 ObjectNotFoundExceptions 正在发生,因为数据库正在删除表行 underneath Hibernate。例如,当我们使用 Hibernate 删除 Parent 时,数据库架构将 ON DELETE CASCADE 到任何 Child 实体。这显然是在没有 Hibernates 知识的情况下发生的,因此它没有机会更新二级缓存(并删除任何已删除的 Child 实体)。

我们认为解决此问题的方法是从我们的数据库架构中删除 ON DELETE CASCADE(但保留 FOREIGN KEYs)。相反,我们需要将 Hibernate 配置为使用普通删除 SQL 删除 Child 依赖项,这也会使 Hibernate 更新二级缓存。一些有限的测试表明这种方法似乎有效。

我想就此获得一些社区反馈。我们的问题有替代(更好的?)解决方案吗?其他人如何处理这种情况?一般来说,在带有 Hibernate 的数据库模式中使用 ON DELETE CASCADE 时应考虑哪些权衡?

谢谢。

【问题讨论】:

    标签: java hibernate foreign-keys second-level-cache


    【解决方案1】:

    如果你总是要通过你的程序进行删除,你想取消数据库的约束,并告诉休眠对象 ON DELETE CASCADE 来照顾相关的人。

    另一方面,如果您有时要在 Java 应用程序中删除对象,有时在数据库级别删除对象,您最终会得到奇怪的挂起数据。在这种情况下,您可能需要研究一种更复杂的方法。您并不清楚是否是这种情况,因此这里不再赘述。

    【讨论】:

    • 好点。数据库只能由我们应用程序中的 Java 代码访问和更新。这种情况不太可能改变。所以删除 ON DELETE CASCADEs 不会影响任何其他应用程序/脚本/等。
    • 然后继续通过hibernate来做
    • 为什么不将数据库ON DELETE CASCADE与hibernate delete cascade结合使用呢?数据库将其删除,休眠尝试删除级联子级,但没有可删除的内容。所以什么都不应该发生,还是我错了?
    • 我认为这可能是一种竞争条件。 Hibernate 为父子 A、B、C 发送删除。数据库删除父 A,然后尝试删除子 A、B、C。这3个的休眠删除失败。休眠是做什么的?错误?无声的例外?不确定...看来您不应该让两个人负责删除同一件事
    • 嗯我觉得没有问题,必须重新评估一下。是否可以强制二级缓存重新检查实体的更新或删除,可能在拦截器内?我自己目前正在努力解决这个问题,我不想删除我的数据库级联效果。实现CASCADESET NULL 可以使用拦截器或EntityListener 来实现。会检查这个。
    【解决方案2】:

    如果你在你的数据库中使用ON DELETE CASCADE,你需要告诉hibernate,像这样:

    @OnDelete(action = OnDeleteAction.CASCADE)
    

    这与

    不同
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    

    后者告诉hibenrate一些关于内存关系的事情。第一个优化了数据库级别的删除 SQL 语句。 Hibernate 需要知道数据库正在处理删除子项。

    查看此站点以了解有关此机制的详细说明:

    http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/

    以及此功能开发者的评论:

    http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg03801.html

    【讨论】:

    • 二级缓存是否与@OnDelete 一起正常工作?所有,我设法找到的:没有 - *.com/a/21155878/548473.
    • 有效!它适用于缓存,完全没有问题。但一如既往:您需要了解它在做什么以及 hibernate 期望什么