2010-06-21 66 views
6

我们的Java应用程序映射到一个数据库(SQL Server或MySQL的)约100班。我们使用Hibernate作为我们的ORM(带有XML映射文件)。Hibernate的二级缓存和ON DELETE CASCADE在数据库架构

我们指定我们的数据库架构FOREIGN KEY约束。我们的大多数FOREIGN KEY约束还指定ON DELETE CASCADE

最近,我们开始启用休眠2级缓存(流行的实体和集合),以减轻一些性能问题。因为我们启用了二级缓存

性能有所提升。但是,我们也开始遇到ObjectNotFoundExceptions。

看来ObjectNotFoundExceptions是存在的,因为数据库中删除表行休眠。例如,当我们用Hibernate删除Parent时,数据库模式将ON DELETE CASCADE到任何Child实体。这显然没有Hibernates的知识,所以它没有机会更新二级缓存(并删除任何已删除的实体)。

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

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

谢谢。

回答

1

如果你总是会通过你的程序删除,要采取约束关闭数据库并告诉Hibernate的对象ON DELETE CASCADE采取相关的人的照顾。

在另一方面,如果你在你的数据库级别要在您的Java应用程序有时删除对象,有时候,你将最终获得怪异吊数据。在这种情况下,您可能需要研究更复杂的方法。您不清楚这是否是这种情况,所以在此不打算详细讨论。

+0

好一点。数据库仅在我们的应用程序中由Java代码访问和更新。这种情况不太可能改变。因此删除ON DELETE CASCADE不会影响任何其他应用程序/脚本等。 – 2010-06-21 21:46:10

+0

然后继续并通过休眠来实现 – bwawok 2010-06-21 22:36:57

+0

为什么不将数据库'ON DELETE CASCADE'与休眠删除级联结合使用?数据库删除它,休眠试图删除级联的孩子,但没有删除。所以什么都不应该发生,或者我错了吗? – djmj 2013-07-31 16:49:05

1

如果在数据库中使用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/[email protected]/msg03801.html

+0

二级缓存是否正确使用@OnDelete?所有,我设法找到:不 - http://stackoverflow.com/a/21155878/548473。 – GKislin 2017-01-14 14:41:46

+1

它的工作原理!它适用于缓存,完全没有问题。但是一如既往:您需要了解它在做什么以及hibernate期望的内容 – Janning 2017-01-14 18:32:23