Hibernate cache di secondo livello e ON DELETE CASCADE in schema del database
-
28-09-2019 - |
Domanda
La nostra applicazione Java ha circa 100 classi mappati a un database (SQL Server o MySQL). Stiamo usando Hibernate come il nostro ORM (con file di mapping XML).
specificare vincoli FOREIGN KEY
nel nostro schema del database. La maggior parte dei nostri vincoli FOREIGN KEY
specificare anche ON DELETE CASCADE
.
Abbiamo recentemente iniziato consentendo Sospensione secondo la cache di livello (per i soggetti popolari e raccolte) per mitigare alcuni problemi di prestazioni.
Performance è migliorata da quando abbiamo attivato la cache di 2 ° livello. Tuttavia abbiamo anche iniziato a incontrare ObjectNotFoundExceptions.
Sembra che i ObjectNotFoundExceptions si verificano perché il database è l'eliminazione di righe della tabella sotto Sospensione. Ad esempio, quando si elimina un Parent
con Hibernate, lo schema del database sarà ON DELETE CASCADE
a qualsiasi entità Child
. Questo accade, ovviamente, senza la conoscenza Hibernates, in modo da non avere la possibilità di aggiornare la cache di 2 ° livello (e rimuovere eventuali entità Child
cancellati).
Si crede che la soluzione a questo problema è quello di rimuovere ON DELETE CASCADE
dal nostro schema di database (ma mantenere le FOREIGN KEY
s). Invece, abbiamo bisogno di configurare Hibernate per le dipendenze Child
cancellazione con normale SQL cancellazione che sarà anche rendere aggiornamento Hibernate la cache di 2 ° livello. Alcuni test limitati hanno dimostrato che questo approccio sembra funzionare.
Volevo ottenere un feedback della comunità su questo. Ci sono alternative migliori (?) Soluzioni al nostro problema? Come fanno gli altri gestire questa situazione? In generale, quali sono i compromessi che dovrebbero essere considerati quando si utilizza ON DELETE CASCADE
in uno schema di database con Hibernate?
Grazie.
Soluzione
Se si sta andando sempre di eliminare attraverso il vostro programma, si vuole prendere il vincolo al largo della base di dati e dire l'oggetto di ibernazione su ON DELETE CASCADE per prendersi cura dei relativi ragazzi.
D'altra parte, se avete intenzione di eliminare gli oggetti a volte nella vostra app Java, e, talvolta, al tuo livello di database, si finirà con i dati appeso strano. In questo caso potrebbe essere necessario guardare in un approccio più complicato .. Non eri chiaro se questo era il caso, in modo da non andare ad andare più in dettaglio qui.
Altri suggerimenti
Se si utilizza ON DELETE CASCADE
nel database è necessario dire a Hibernate, in questo modo:
@OnDelete(action = OnDeleteAction.CASCADE)
questo è diverso da
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
Il secondo sta dicendo hibenrate qualcosa sul rapporto in memoria. il primo consente di ottimizzare istruzioni SQL Elimina dal livello di database. Hibernate ha bisogno di sapere che il DB sta prendendo cura di bambino di eliminazione.
Date un'occhiata a questo sito per una buona spiegazione di questo meccanismo:
http://eddii.wordpress.com/2006 / 11/16 / hibernate-on-deletecascade-prestazioni /
e il commento da parte dello sviluppatore di questa funzione:
http: //www.mail-archive. com/hibernate-devel@lists.sourceforge.net/msg03801.html