7

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

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

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

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

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

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

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

谢谢。

4

2 回答 2

2

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

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

于 2010-06-21T18:15:44.120 回答
1

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

@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

于 2014-03-08T10:39:52.743 回答