Contrôler la session d’hibernation (quand la fermer manuellement)

Je suis nouveau dans l’hibernation, après avoir lu l’API et le tutoriel d’hibernation, il semble que la session devrait être fermée lorsqu’elle n’est pas utilisée.

Comme ça:

Session sess=getSession(); Transcration tx=sess.beginTranscration(); //do something using teh session sess.save(obj); tx.commit(); sess.close; 

Je n’ai aucune question lorsque je l’utilise dans une application autonome. Cependant, je ne suis pas sûr d’utiliser cette application Web.

Par exemple, j’ai un servlet: TestServlet pour recevoir les parameters du client, puis j’appelle un gestionnaire pour interroger quelque chose en fonction des parameters, comme ceci:

 class TestServlet{ doGet(HttpServletRequset,httpServletResponse){ Ssortingng para1=request.getParam...(); Ssortingng para2=..... new Manager().query(para1,para2); } } class Manager{ public Ssortingng query(Ssortingng pa1,Ssortingng pa2){ Session=....// get the session //do query using para1 and 1 session.close() //Here, I wonder if I should close it. } } 

Dois-je fermer la session dans la méthode de requête?

Depuis que quelqu’un m’a dit que la session en veille prolongée était comme la connexion en jdbc. Donc, ouvrir et fermer si souvent est la bonne façon?

BTW, le tx.commit () est-il requirejs à chaque fois?

De plus, quel est le problème du thread concernant l’utilisation de la session dans servlet, car j’ai vu que la session n’est pas thread-safe dans api.

Je suis nouveau dans l’hibernation, après avoir lu l’API et le tutoriel d’hibernation, il semble que la session devrait être terminée lorsqu’elle n’est pas utilisée.

Il devrait être fermé lorsque vous en avez fini avec (mais cela peut être fait automatiquement pour nous comme nous le verrons).

Je n’ai aucune question lorsque je l’utilise dans une application autonome. Cependant, je ne suis pas sûr d’utiliser cette application Web.

Eh bien, comme expliqué dans la section 11.1.1. Unité de travail de la documentation, le modèle le plus courant dans une application client / serveur multi-utilisateur est session-per-request .

Par exemple, j’ai un servlet: TestServlet pour recevoir les parameters du client, puis j’appelle un gestionnaire pour interroger quelque chose en fonction des parameters: juste comme ça (…) Dois-je fermer la session dans la méthode de requête?

Tout dépend de la façon dont vous obtenez la session.

  • Si vous utilisez sessionFactory.getCurrentSession() , vous obtiendrez une “session en cours” qui est liée au cycle de vie de la transaction et sera automatiquement vidée et fermée à la fin de la transaction (validation ou annulation).
  • Si vous décidez d’utiliser sessionFactory.openSession() , vous devrez gérer la session vous-même et la vider et la fermer “manuellement”.

Pour implémenter un modèle de session par requête , préférez la première approche (beaucoup plus facile et moins verbeuse). Utilisez la deuxième approche pour mettre en œuvre de longues conversations .

La page wiki Sessions et transactions complète bien la documentation sur ce sujet.

BTW, le tx.commit () est-il requirejs à chaque fois?

Vous voudrez peut-être lire l’access aux données non transactionnelles et le mode de validation automatique pour clarifier quelques points, mais pour le dire simplement, votre code Hibernate doit être exécuté dans une transaction et je suggère d’utiliser des limites de transaction explicites (par exemple: explicite beginTransaction et commit ).

De plus, quel est le problème du thread concernant l’utilisation de la session dans servlet, car j’ai vu que la session n’est pas thread-safe dans api.

Il suffit de ne pas en faire une variable d’instance de la Servlet et vous n’aurez aucun problème.

Les références

  • Guide de référence d’Hibernate Core 3.3
    • Chapitre 11. Transactions et access concurrents
  • Hibernate wiki
    • Sessions et transactions
    • Accès aux données non transactionnel et mode auto-commit

Si vous obtenez une session via sessionFactory.openSession() vous devez la fermer en externe . Une session ouverte pour une période imprévue peut provoquer des fuites de données. De plus, il peut inviter à la menace de sécurité Web App.

Nous pouvons utiliser ThreadLocal .

 public class MyUtil { private static SessionFactory sessionFactory; private static ServiceRegistry serviceRegistry; private static final ThreadLocal threadLocal; static { try { Configuration configuration = new Configuration(); configuration.configure(); serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); threadLocal = new ThreadLocal(); } catch(Throwable t){ t.printStackTrace(); throw new ExceptionInInitializerError(t); } } public static Session getSession() { Session session = threadLocal.get(); if(session == null){ session = sessionFactory.openSession(); threadLocal.set(session); } return session; } public static void closeSession() { Session session = threadLocal.get(); if(session != null){ session.close(); threadLocal.set(null); } } public static void closeSessionFactory() { sessionFactory.close(); StandardServiceRegistryBuilder.destroy(serviceRegistry); } } 

Ici, la SessionFactory est initialisée une seule fois en utilisant le bloc statique. Par conséquent, chaque fois que la classe main appelle getSession() , la présence de l’object Session est d’abord vérifiée dans l’object threadLocal . Par conséquent, ce programme fournit la sécurité des threads. Après chaque opération, closeSession() ferme la session et définit l’object threadLocal sur null. Appelez enfin closeSessionFactory() .