2010-06-21 65 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