Comportement de vidage de session Hibernate [et Spring @Transactional]
J'utilise Spring et Hibernate dans une application web,
SessionFactory est injecté dans un DAO bean, et puis ce n'DAO est utilisé dans une Servlet par webservicecontext.
DAO méthodes transactionnelles, à l'intérieur de l'une des méthodes que j'utilise ... getCurrentSession().enregistrer(monobjet);
Une servlet appelle cette méthode avec un objet passé.
La mise à jour ne semble pas être vidées à la foisil faut environ 5 secondes pour voir les modifications dans la base de données. La servlet est la méthode dans laquelle le DAO de la mise à jour de la méthode est appelée, ne prend qu'une fraction de seconde pour terminer.
Après le @Transactional méthode de DAO est terminé, les bouffées de chaleur ne peut PAS arriver ? Il ne semble pas être une règle [ j'ai déjà le voir ].
Alors la question est: est-ce que faire de la force de la session de rincer après chaque méthode DAO?
Il peut ne pas être une bonne chose à faire, mais parler d'une couche de Service, certaines méthodes doit prendre fin immédiatement rincer, et la Session Hibernate comportement n'est pas prévisible.
Alors, que faire pour garantir que ma @Transactional méthode persiste toutes les modifications après la dernière ligne de code de la méthode?
getCurrentSession().flush() is the only solution?
p.s. J'ai lu quelque part que @Transactionnelle EST ASSOCIÉ à une base de Transaction. Méthode retourne, la transaction doit être validée.
Je ne vois pas ce qui se passe.
source d'informationauteur EugeneP | 2010-05-20
Vous devez vous connecter pour publier un commentaire.
Une fois le "haut niveau" @Transactionnelle de la méthode est terminée (c'est à dire la méthode est appelée à partir de votre servlet), alors la transaction doit être validée, et la valeur par défaut Hibernate comportement est à la chasse sur les commettre.
Ça sonne comme quelque chose de bizarre qui se passe et vous devriez faire un peu d'investigation.
Enquêter sur vos journaux, en particulier je voudrais définir le niveau de journalisation de DÉBOGAGE sur votre Gestionnaire de Transactions pour voir exactement ce que le gestionnaire de transactions est en train de faire.
Aussi, réglez le niveau d'enregistrement sur pour mettre en veille prolongée (ensemble show_sql à true): ce sera la sortie du Système.hors lorsque les bouffées de chaleur qui se passe et ce qui pourrait vous donner quelques indices.
Faire un rapport si vous trouvez quelque chose d'intéressant.
Étonner je pense que celui-être réponse exacte qui peut résoudre une telle situation exacte, vous pouvez utiliser
FlushMode.ALWAYS
pour DAO particulier chaque fois que vous avez besoin de rincer session de restreindre complètement après chaque transaction.ALWAYS
flushmode n'est pas préférable, car elle est coûteuse, mais comme vous conviennent, vous pouvez sessions multiples usine avec différents flushmode pour différents besoins.J'ai eu ce problème aussi!
Je suis l'aide de Printemps annotation de transaction (@Transactionnelle) et je me fais un peu de méthode, en train de faire la session.flush(), et d'autres pas!
De mon journal de débogage j'ai:
transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
La session.close() doit être appelée à partir du Printemps TransationManager, mais je ne suis pas sûr de ce qu'il se passe: j'ai vérifié mon Ressort de configuration et je ne peux pas expliquer pourquoi ce qui se passe. De plus, j'enquête et je vais reposter tout soupçon, mais si quelqu'un a quelques conseils utiles je'ld être très reconnaissant :o)
Mise à jour: Le problème semble lié à la session hibernate flush mode = MANUEL: il n'a pas d'évacuer les objets à la fin du Printemps de l'opération.
Vous pouvez vérifier votre actuelle flush mode avec quelque chose comme:
MISE À JOUR [RÉSOLU POUR MOI]:
J'ai creusé beaucoup dans mon problème et a trouvé l'origine du problème et une solution de contournement.
J'ai eu, comme vous, si je comprends bien, un problème intermittent où certaines transactions ont été fermé correctement (c'est à dire les sessions hibernate ont été vidées) et quelques autres pas.
J'ai découvert que:
le problème était dû à
flushMode
ensemble deFlushMode.MANUAL
quand je suis entré dans la transaction (que de ne pas déclencher l'opération de vidage lors de la validation de transaction);ceci était dû à quelque chose de méchant en cours entre le Printemps et ZK (les mauvaises transactions étaient tous de ZK est compositeurs - si vous ne savez pas ZK, ils sont appelés par les servlets, à peu près équivalent à Struts' actions);
précisément le problème réside dans le Ressort de la
OpenSessionInViewFilter
communique pas correctement avec ZK filtres: la session Hibernate fournis parOpenSessionInViewFilter
est de ne pas obtenir son rincer correctement en mode set. Le seul ZK compositeur fonctionne bien (je l'ai testé à partir de certains tests JUnit), ainsi que laOpenSessionInViewFilter
seul (je l'ai testé à partir d'une simple Servlet utilisantWebApplicationContextUtils
).Conclusion: j'appelle
session.flush()
à la fin de chaque @Transactional méthode dans mes compositeurs, et je vais migrer vers Vaadin (beaucoup, beaucoup plus simple à intégrer, paraît-il).Pour votre besoin particulier (rinçage à chaque DAO appel de méthode), vous pouvez définir la session flush mode de FlushMode.TOUJOURS. À partir de la documentation hibernate:
définition de la "mise en veille prolongée.des transactions.flush_before_completion" true à la propriété peut aider.
https://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/
"Si activé, la session sera automatiquement supprimées au cours de la avant la phase d'achèvement de la transaction. Intégré et automatique de session, gestion de contexte est préféré, voir la Section 2.5, “des sessions Contextuelles”".
Je ne recommandent pas l'utilisation de mise en veille prolongée.des transactions.flush_before_completion à l'échelle mondiale pour des raisons de performances.
Alternativement, vous pouvez gérer les transactions de vous-même: