在数据库模式中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
到任何子实体。 这显然没有Hibernates知识,所以它没有机会更新二级缓存(并删除任何已删除的子实体)。
我们相信这个问题的解决方案是从我们的数据库模式中删除ON DELETE CASCADE
(但保留FOREIGN KEY
)。 相反,我们需要配置Hibernate以使用普通删除SQL删除Child
依赖项,这也将使Hibernate更新二级缓存。 一些有限的测试表明这种方法似乎有效。
我想得到一些社区反馈。 我们的问题是否有其他(更好的?)解决方案? 其他人如何处理这种情况? 通常,在使用Hibernate的数据库模式中使用ON DELETE CASCADE
时应该考虑哪些权衡?
谢谢。
如果你总是要通过你的程序删除,你想要从数据库中取出约束并告诉hibernate对象ON DELETE CASCADE来处理相关人员。
另一方面,如果您要在Java应用程序中删除某些对象,有时在数据库级别,则最终会出现奇怪的挂起数据。 在这种情况下,你可能需要研究一个更复杂的方法..你不清楚是否是这种情况,所以不打算在这里详细介绍。
如果你在数据库中使用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/
以及此function的开发人员的评论:
http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg03801.html