# applikationsverwalteter EntityManager in contextInitialized



## Felli (14. Nov 2008)

Heute morgen bekam ich beim Anmelden an meine Webanwendung die Fehlernachricht „Transaction is not active“. Ich habe nun ein Frage bezüglich meines Vorgehens zum Erzeugen des EntityManagerFactory-Exemplars, welches in diesem Fall nicht durch einen Container verwaltet wird.

In der contextInitialized-Methode des ServletContextListener wird das Objekt etwa so erzeugt:


```
ServletContext context = event.getServletContext();
    EntityManagerFactory emf = EntityManagerFactoryUtil.getEntityManagerFactory();
    context.setAttribute(Konstanten.ENTITY_MANAGER_FACTORY, emf);
```

Die Implementierung für contextDestroyed sieht ungefähr so aus:


```
EntityManagerFactory emf = (EntityManagerFactory)context.getAttribute(Konstanten.ENTITY_MANAGER_FACTORY);
     emf.close();
```

Ich verwende Struts 2. Das EntityManagerFactory-Objekt wird mit Hilfe eines Interceptors an die jeweiligen Aktionsklassen geleitet. 

Es ist meine erste Webanwendung, in der ich JPA verwende und wollte nun fragen, ob dieses Vorgehen so in Ordnung ist und was man vielleicht noch beachten sollte. Sonst muss ich warten, bis der Fehler wieder auftritt und verfolgen.


----------



## Felli (18. Nov 2008)

OK, die Ausnahme entsteht durch einen Timeout. Das ist die eigentliche Meldung:


```
The last packet successfully received from the server was172252 milliseconds ago.The last packet sent successfully to the server was 172252 milliseconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
```

Ich verwende MySql und Connector/J. Seltsamerweise wird in den Dokumentationen immer wieder daraufhingewiesen, dass die Eigenschaft autoReconnect nicht verwendet werden soll. Ich schaue mal nach, ob ich für das Problem eine andere Lösung finde.


----------



## Felli (26. Nov 2008)

Irgendwie führe ich einen Monolog ...

Na gut, der MySQL-Server hat die Eigenschaft wait_timeout mit dem Standardwert 28800 (Sekunden). Dies lässt sich mit _mysqladmin variables_ anzeigen. Nach dieser Zeit schmieren die Verbindungen ab. 

Also muss c3p0 so eingestellt werden, dass die Connection-Exemplare zuvor einem Test unterzogen werden. Ab Hibernate 3 können beispielsweise diese Eigenschaften verwendet werden:


```
<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> 
  <property name="c3p0.min_size">5</property> 
  <property name="c3p0.max_size">100</property> 
  <property name="c3p0.max_statements">50</property> 
  <property name="c3p0.idle_test_period">14400</property>
```

Durch idle_test_period wird alle 14400 Sekunden ein Test durchgeführt. Die Verbindungen im Pool sollten somit erhalten bleiben. Ob's geklappt hat, sehe ich dann morgen.

...

Ja, funktioniert so.


----------

