在数据库模式中休眠二级缓存和ON DELETE CASCADE

时间:2010-06-21 17:45:05

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

我们的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个实体。这显然没有Hibernates知识,所以它没有机会更新二级缓存(并删除任何已删除的Child实体)。

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

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

感谢。

2 个答案:

答案 0 :(得分:1)

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

另一方面,如果您要在Java应用程序中删除对象,有时在数据库级别删除对象,则最终会出现奇怪的挂起数据。在这种情况下,你可能需要研究一个更复杂的方法..你不清楚是否是这种情况,所以不打算在这里详细介绍。

答案 1 :(得分:1)

如果您在数据库中使用ON DELETE CASCADE,则需要告诉hibernate,如下所示:

@OnDelete(action = OnDeleteAction.CASCADE)

这与

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

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

请查看此网站以获得有关此机制的详细说明:

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

以及此功能开发人员的评论:

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