9
votes

Hibernate: cache de 2e niveau de la collection de nettoyer en cascade Supprimer des éléments

J'ai un problème hibernate ne met pas à jour le cache de 2e niveau pour une collection d'articles qui font l'objet d'un retrait de cascade.

Détails

Supposons que nous avons un parent objet qui a parent.mychildren Collection d'objets enfants. Maintenant, nous avons aussi des objets humains avec Humans.MyLallhumans et tous les objets parent et enfants sont dans cette collection.
Maintenant, nous session.Delete (parent) et tous les enfants sont en cascade supprimés de la base de données, mais l'Humans.MaLallhumans Cache Cache n'est pas mis à jour! Il suppose toujours que les objets supprimés de cascade sont dans la base de données et nous avons frappé à la suite d'une exception tout en essayant d'iRser la collection plus tard:
org.hibernate.ObjectNotFoundException: Aucune ligne avec l'identifiant donné n'existe: [foo.child # 751]

approches essayées

1) J'ai essayé SéanceFactory.evictCollection () Approche, mais si je comprends, il ne s'agit pas de transaction sûre et que le dur supprime les données du 2e cache de niveau, je ne le souhaite pas.

2) Je peux également supprimer manuellement (programme) supprimer chaque objet de la collection MyallHumans. Dans ce cas, Hibernate met à jour le cache de 2e niveau. Cette approche que je voudrais éviter car elle fait simplement une fonctionnalité de suppression en cascade inutile.

attendu

J'aimerais que Hibernate soit suffisamment intelligente pour mettre à jour le cache de la collection automatiquement. Est-ce possible?
J'utilise ehcache maintenant, pensez-vous en utilisant une autre implémentation de cache ou configurer EHCache peut aider?


3 commentaires

Je suppose que mon cas problématique peut être simplifié. Supposons que j'appelle juste "session.delete (enfant)", comment puis-je être sûr parent.mychildren 2nd Le cache est synchronisé?


S'il indique Aucune ligne avec l'identifiant donné n'existe pas , qui suggère que c'est le cache de requête qui n'est pas mis à jour ... utilisez-vous la mise en cache de requête ou une mise en cache de 2e niveau unique?


Jetez un coup d'œil au même problème question: Stackoverflow.com/Questtions/3087040/...


3 Réponses :


1
votes

Le problème est que Hibernate ne fait pas réellement la suppression. La base de données fait cela dans le cadre d'une relation de clé étrangère, donc hibernate ne voit jamais tous les objets pouvant être supprimés et donc, il n'ya aucun moyen de mettre à jour le cache qui fonctionne dans tous les cas.

Je pense que votre meilleur pari est de rincer le cache (ou la partie de celui-ci) lorsque vous supprimez.


4 commentaires

Je n'utilise pas sur-Supprimer = "cascade" ici (c.-à-d. Cascade de niveau de la base de données), j'utilise cascade = "Supprimer" à la place (c'est-à-dire que Hibernate doit appeler "Supprimer" de manière récursive, ne devrait-il pas?) Et sur le " affleurer". Je m'engage à la fin, ça ne force pas de flush?


Voyez-vous des lots d'hibernate beaucoup de suppressions dans le journal?


Mais Hibernate peut savoir si l'entité sera supprimée de cascade.


J'attends toujours une confirmation qu'il utilise la configuration correcte et voit réellement l'émission hibernate émettant des déclarations supprimer . S'il le fait, alors il doit peut-être rafraîchir l'instance humains parce que c'est rassis.



0
votes

Habituellement, hibernate besoin d'un rafraîchissement politiquement incorrect de l'objet de recharger le Cahe.

Une chose importante est la façon dont EHCache gère les propriétés paresseuses. J'ai trouvé que l'attribut paresseux de la collection n'est pas défini, le Cahe ne rafraîchit pas les objets.

Dans votre cas, si l'ensemble des humains de l'attribut de l'humanité est défini sur Lazy = TRUE (option par défaut), ehcache ne l'actualise pas si l'objet. Essayez de définir l'attribut paresseux des collections d'humains et d'enfants à FALSE.


0 commentaires

1
votes

J'ai eu des difficultés avec d'autres problèmes nécessitant supprimer la collection du cache et j'ai élaboré une solution. Je ne sais pas s'il est possible de mettre à jour le cache de la collection automatiquement sur Cascade Suppr, mais si vous avez essayé SessionFactory.evictCollection () et cela a fonctionné, je pense que cette solution peut être sécuritaire transactionnelle et que cela fonctionne également:

si (instance myCollection d'abstractmersistentCollection) ((abstractpersistentencollection) mycollection) .Dirty ();


0 commentaires