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 KEYs). 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.

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top