2010-06-21 6 views
6

Notre application Java a environ 100 classes mappées à une base de données (SQL Server ou MySQL). Nous utilisons Hibernate comme ORM (avec des fichiers de mapping XML).Hibernate cache de second niveau et ON DELETE CASCADE dans le schéma de base de données

Nous spécifions FOREIGN KEY contraintes dans notre schéma de base de données. La plupart de nos contraintes FOREIGN KEY spécifient également ON DELETE CASCADE.

Nous avons récemment commencé à activer la mise en mémoire cache de second niveau Hibernate (pour les entités et collections populaires) afin d'atténuer certains problèmes de performances.

Les performances se sont améliorées depuis que nous avons activé le cache de deuxième niveau. Cependant, nous avons également commencé à rencontrer ObjectNotFoundExceptions.

Il semble que les ObjectNotFoundExceptions sont INTERVENUES parce que la base de données supprime les lignes de table sous Mise en veille prolongée. Par exemple, lorsque nous supprimons un Parent avec Hibernate, le schéma de la base de données ON DELETE CASCADE vers toutes les entités Child. Cela se produit évidemment sans connaissance Hibernates, donc il n'a pas l'occasion de mettre à jour le cache de second niveau (et de supprimer toutes les entités Child).

Nous croyons que la solution à ce problème est d'enlever ON DELETE CASCADE de notre schéma de base de données (mais gardez le s). Au lieu de cela, nous devons configurer Hibernate pour supprimer les dépendances Child avec le SQL normal de suppression qui fera également mettre à jour Hibernate le cache de 2ème niveau. Des tests limités ont montré que cette approche semble fonctionner.

Je voulais obtenir des commentaires de la communauté à ce sujet. Existe-t-il des solutions alternatives (meilleures?) À notre problème? Comment les autres gèrent-ils cette situation? En général, quels sont les compromis à prendre en compte lors de l'utilisation de ON DELETE CASCADE dans un schéma de base de données avec Hibernate?

Merci.

Répondre

1

Si vous allez toujours supprimer à travers votre programme, vous voulez supprimer la contrainte de la base de données et dire à l'objet Hibernate de ON DELETE CASCADE pour prendre soin des gars liés. D'autre part, si vous allez supprimer des objets parfois dans votre application java, et parfois au niveau de votre base de données, vous finirez avec des données suspendues étranges. Dans ce cas, vous devrez peut-être vous pencher sur une approche plus compliquée. Vous n'étiez pas clair si c'était le cas, alors vous n'allez pas entrer dans plus de détails ici.

+0

Bon point. La base de données n'est accessible et mise à jour que par le code Java dans notre application. Cette situation est peu susceptible de changer. Ainsi, supprimer les CASCADE ON DELETE n'affecterait PAS les autres applications/scripts/etc. –

+0

Alors allez-y et faites-le via Hibernate – bwawok

+0

Pourquoi ne pas laisser la base de données 'ON DELETE CASCADE' en combinaison avec Hibernate Delete Cascade? base de données le supprime, Hibernate essaie de supprimer l'enfant en cascade mais rien à supprimer. Donc, rien ne devrait arriver ou ai-je tort? – djmj

1

Si vous utilisez ON DELETE CASCADE dans votre base de données dont vous avez besoin de dire mise en veille prolongée, comme ceci:

@OnDelete(action = OnDeleteAction.CASCADE) 

ceci est différent de

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 

Ce dernier est dit quelque chose hibenrate sur l'en mémoire relation. le premier optimise la suppression des instructions SQL au niveau de la base de données. Hibernate doit savoir que la base de données s'occupe de supprimer les enfants.

Jetez un oeil à ce site pour une bonne explication de ce mécanisme:

http://eddii.wordpress.com/2006/11/16/hibernate-on-deletecascade-performance/

et le commentaire du développeur de cette fonctionnalité:

http://www.mail-archive.com/[email protected]/msg03801.html

+0

Le cache de second niveau fonctionne-t-il correctement avec @OnDelete? Tous, ce que je parviens à trouver: non - http://stackoverflow.com/a/21155878/548473. – GKislin

+1

Ça marche! Cela fonctionne avec le cache, pas de problème du tout. Mais comme toujours: Vous devez comprendre ce qu'il fait et ce que Hibernate attend – Janning

Questions connexes