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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.