[JPA][HIBERNATE] Comment utiliser un Singleton ?
Bonjour,
J'utilise Hibernate dans son mode JPA sur une application web (développée sous Struts 2, mais ce n'est pas essentiel). J'utilise aussi le pool de connexion C3PO fourni avec Hibernate.
En Struts 2, chaque requête utilisateur déclenche l'exécution d'une classe "Action", qui appele ensuite une vue (jsp) pour produire l'affichage de ce qu'elle a traité.
Dans chacune de mes classes Action, j'ouvre la connexion vers l'unité de persistence comme ceci :
Code:
1 2 3 4
| EntityManagerFactory emf = Persistence.createEntityManagerFactory(ck.PERSISTENCE_UNIT);
em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); |
Je fais les traitements, initialise les objets à afficher par la JSP, puis ferme la connexion comme ceci :
Code:
1 2 3 4
| // fin transaction
tx.commit();
em.close();
emf.close(); |
Ceci fonctionne à peu près, mais je pense que ce n'est pas optimisé. En effet, après plusieurs requêtes successives ou simultannées, je finis par déclencher des exceptions du genre :
Code:
1 2 3
| 16:22:06,311 ERROR JDBCExceptionReporter:72 - Connections could not be acquired from the underlying database!
16:22:06,322 ERROR [default]:253 - "Servlet.service()" pour la servlet default a généré une exception
com.mchange.v2.resourcepool.CannotAcquireResourceException: A ResourcePool could not acquire a resource from its primary factory or source. |
ou bien :
Code:
1 2 3 4 5 6 7 8 9
| javax.servlet.ServletException: org.hibernate.exception.GenericJDBCException: Cannot open connection
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:515)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419)
cause mère
javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: Cannot open connection
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:647)
org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:40) |
Puis l'application ne réponds plus à mes requêtes.
Est-ce que je procède comme il faut ?
J'en déduis que trop d'instances de connexion sont créées, alors que je pourrais peut-être les limiter en utilisant un Singleton.
Ai-je raison ?
Si oui, comment faire ?
Je pense que c'est un problème de débutant, mais c'est pas évident à résoudre tout seul.
merci de votre aide.