Hibernate 二级缓存和数据库模式中的 ON DELETE CASCADE
我们的 Java 应用程序有大约 100 个映射到数据库(SQL Server 或 MySQL)的类。我们使用 Hibernate 作为 ORM(带有 XML 映射文件)。
我们在数据库模式中指定 FOREIGN KEY
约束。我们的大多数 FOREIGN KEY
约束也指定 ON DELETE CASCADE
。
我们最近开始启用 Hibernate 二级缓存(针对流行的实体和集合)以缓解一些性能问题。
自从我们启用二级缓存以来,性能得到了提高。然而,我们也开始遇到 ObjectNotFoundExceptions。
似乎发生了 ObjectNotFoundExceptions,因为数据库正在删除 Hibernate 下的表行。例如,当我们使用 Hibernate 删除 Parent
时,数据库架构将 ON DELETE CASCADE
到任何 Child
实体。这显然是在 Hibernate 不知情的情况下发生的,因此它没有机会更新二级缓存(并删除任何已删除的 Child
实体)。
我们认为此问题的解决方案是从数据库架构中删除 ON DELETE CASCADE
(但保留 FOREIGN KEY
)。相反,我们需要配置 Hibernate 使用普通删除 SQL 来删除 Child
依赖项,这也会使 Hibernate 更新二级缓存。一些有限的测试表明这种方法似乎有效。
我想获得一些社区对此的反馈。我们的问题是否有替代(更好?)的解决方案?其他人如何处理这种情况?一般来说,在 Hibernate 的数据库模式中使用 ON DELETE CASCADE 时应考虑哪些权衡?
谢谢。
Our Java application has about 100 classes mapped to a database (SQL Server or MySQL). We are using Hibernate as our ORM (with XML mapping files).
We specify FOREIGN KEY
constraints in our database schema. Most of our FOREIGN KEY
constraints also specify ON DELETE CASCADE
.
We've recently started enabling Hibernate 2nd level caching (for popular entities and collections) to mitigate some performance problems.
Performance has improved since we enabled the 2nd level cache. However we've also started encountering ObjectNotFoundExceptions.
It seems the ObjectNotFoundExceptions are occuring because the database is deleting table rows underneath Hibernate. For example, when we delete a Parent
with Hibernate, the database schema will ON DELETE CASCADE
to any Child
entities. This obviously happens without Hibernates knowledge, so it doesn't get a chance to update the 2nd level cache (and remove any deleted Child
entities).
We believe the solution to this problem is to remove ON DELETE CASCADE
from our database schema (but keep the FOREIGN KEY
s). Instead, we need to configure Hibernate to delete Child
dependencies with normal delete SQL which will also make Hibernate update the 2nd level cache. Some limited testing has shown that this approach seems to work.
I wanted to get some community feedback on this. Are there alternative (better?) solutions to our problem? How do others handle this situation? In general, what are the tradeoffs that should be considered when using ON DELETE CASCADE
in a database schema with Hibernate?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您总是要通过程序进行删除,则需要取消数据库的约束,并告诉 hibernate 对象 ON DELETE CASCADE 来处理相关的事情。
另一方面,如果您有时要在 Java 应用程序中删除对象,有时要在数据库级别删除对象,那么您最终会得到奇怪的挂起数据。在这种情况下,您可能需要研究更复杂的方法。您不清楚是否是这种情况,因此这里不打算详细介绍。
If you are always going to delete through your program, you want to take the constraint off the database and tell the hibernate object to ON DELETE CASCADE to take care of the related guys.
On the other hand, if you are going to delete objects sometimes in your java app, and sometimes at your database level, you will end up with weird hanging data. In this case you may need to look into a more complicated approach.. You weren't clear if this was the case, so not going to go into more detail here.
如果您在数据库中使用
ON DELETE CASCADE
,您需要告诉hibernate,如下所示:不同
这与后者告诉hibernate有关内存中关系的信息 。第一个在数据库级别优化删除 SQL 语句。 Hibernate 需要知道数据库正在处理删除子项。
请查看此网站,了解此机制的详细解释:
http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/
以及此功能开发人员的评论:
http://www.mail-archive.com/[电子邮件受保护]/msg03801.html
If you are using
ON DELETE CASCADE
in your database you need to tell hibernate, like this:this is different from
The latter is telling hibenrate something about the in-memory relationship. the first one optimizes delete SQL Statements on the database level. Hibernate needs to know that the DB is taking care of delete childs.
Take a look at this site for a good explanation of this mechanism:
http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/
and the comment from the developer of this feature:
http://www.mail-archive.com/[email protected]/msg03801.html