# Tomcat, Hibernate, MySQL und die EOFException



## Mr_Blonde (5. Mai 2007)

Servus,

ich habe bei mir das klassische Problem. Ich benutze Hibernate, MySQL und einen beliebigen Connection Pool (C3P0, DBCP). Anfänglich funktioniert alles wunderbar, doch noch einer Weile inaktivität (> 12h) funktioniert kein Datenbankzugriff mehr.

Hier ist die Fehlermeldung:


> com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
> 
> ** BEGIN NESTED EXCEPTION **
> 
> ...



Das Problem wird ja oft in Foren angesprochen, doch nirgends finde ich eine Lösung, welche bei mir funktioniert. Ab und zu wird zwar geschrieben, dass es mit dieser oder jener Einstellung funktionieren soll, aber alles Ausprobierte brachte mich nicht weiter. Teilweise sind auch die Ratschläge in unterschiedlichen Foren/Mailinglisten wiedersprüchlich.

Meine Frage daher: Hat jemand eine Hibernate Config, die funktioniert? Hat eventuell schonmal jemand ein ähnliches Problem gelöst?

Bin für jeden Hinweis dankbar.

Hier ist meine momentane Hibernate Config:

```
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">XYZ</property>
        <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1/k2?useUnicode=true&connectionCollation=utf8_general_ci&characterSetResults=utf8</property>
        <property name="hibernate.connection.username">XYZ</property>
	<property name="hibernate.connection.is-connection-validation-required">true</property>
		
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.current_session_context_class">thread</property>

		
		<property name="hibernate.dbcp.maxActive">100</property>
		<property name="hibernate.dbcp.whenExhaustedAction">1</property>
		<property name="hibernate.dbcp.maxWait">20000</property>
		<property name="hibernate.dbcp.maxIdle">10</property>
		
		
		<property name="hibernate.dbcp.ps.maxActive">100</property>
		<property name="hibernate.dbcp.ps.whenExhaustedAction">1</property>
		<property name="hibernate.dbcp.ps.maxWait">120000</property>
		<property name="hibernate.dbcp.ps.maxIdle">100</property>
		
		
		<property name="hibernate.dbcp.validationQuery">select 1 from hibernate_unique_key</property>
		<property name="hibernate.dbcp.testOnBorrow">true</property>
		<property name="hibernate.dbcp.testOnReturn">true</property> 

   
        
      

      [..]

    </session-factory>
</hibernate-configuration>
```

Benutzte Versionen:
Tomcat: 6.0.10.0
Hibernate: 3.2.2
MySQL: 5.0.32
JVM Version: 1.5.0_10-b03


Schönes Wochenende noch!


----------



## nero30 (9. Mai 2007)

schliesse mich an, hab genau das selbe Problem allerdings mit Toplink und Java 1.6.0. Der Fehler passiert bei update-Statements.


----------



## KSG9|sebastian (9. Mai 2007)

Das ist doch nicht der komplette Stacktrace?! Zeig mal den Rest her..
Und bitte das Codesnippet bei dem die Exception auftritt.

gruß sebastian


----------



## nero30 (10. Mai 2007)

ich mische mich nochmal ein 
bei mir sieht das so aus: 


```
[TopLink Warning]: 2007.05.10 06:17:16.293--ClientSession(12964119)--Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.0 (Build b44-beta3 (04/25/2007))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception: 

** BEGIN NESTED EXCEPTION ** 

java.io.EOFException

STACKTRACE:

java.io.EOFException
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1963)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2375)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2874)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
        at com.mysql.jdbc.Connection.execSQL(Connection.java:3243)
        at com.mysql.jdbc.Connection.setAutoCommit(Connection.java:5371)
        at oracle.toplink.essentials.internal.databaseaccess.DatabaseAccessor.basicBeginTransaction(DatabaseAccessor.java:159)
        at oracle.toplink.essentials.internal.databaseaccess.DatasourceAccessor.beginTransaction(DatasourceAccessor.java:144)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.basicBeginTransaction(AbstractSession.java:283)
        at oracle.toplink.essentials.threetier.ClientSession.basicBeginTransaction(ClientSession.java:123)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.beginTransaction(AbstractSession.java:378)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.beginTransaction(UnitOfWorkImpl.java:419)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.beginEarlyTransaction(UnitOfWorkImpl.java:409)
        at oracle.toplink.essentials.queryframework.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:67)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:613)
        at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:540)
        at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2219)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937)
        at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:909)
        at oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.executeUpdate(EJBQueryImpl.java:372)
        at business.COnlineshop.updateProductsQuantities(COnlineshop.java:174)
        at business.CTransferObjectsAssembler.updateProductsQuantities(CTransferObjectsAssembler.java:171)
        at rmi.CRemoteService.updatesProductsQuantities(CRemoteService.java:71)
        at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
        at sun.rmi.transport.Transport$1.run(Transport.java:159)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
        at java.lang.Thread.run(Thread.java:619)


** END NESTED EXCEPTION **



Last packet sent to the server was 62 ms ago.
Error Code: 0
```


eine der Funktionen in der das passiert macht eigentlich nur das:


```
EntityManager em=emf.createEntityManager();
.
.
.
Query q = em.createNativeQuery("update products set products_quantity=?1 where products_model=?2");
q.setParameter(1,menge);
q.setParameter(2,artikelnr);
            
em.getTransaction().begin();
int erg=q.executeUpdate();
em.getTransaction().commit();
```

ist der Fehler einmal passiert, funktionieren keine Update-Queries mehr, es gibt dann immer diese Exception, selects funktionieren weiterhin (benötigen auch keine Transaktionen).


----------



## Mr_Blonde (11. Mai 2007)

Die ganze Ausgabe ist etwas viel um hier gepostet zu werden. Ich habe den kompletten Trace hier hochgeladen (html)

Stack trace

Das Problem tritt bei jedem Datenbank-Zugriff auf. Allerdings nur nach einer längeren Zeit von Inaktivität.
Hier ist ein Codestück, bei dem das Problem z.B. auftritt:


```
public List<Trip> getAllTrips() {
		List<Trip> tripList = new ArrayList<Trip>();
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		
		// sort trips by trip start date
		Query q = session.createQuery("FROM Trip t ORDER BY t.startDate ASC");
		
		// get the list
		tripList = q.list();
		
		return tripList;
	}
```

Dies ist die Klasse HibernateUtil:


```
public class HibernateUtil {

    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}
```


----------



## ptriller (19. Mai 2007)

Ich würde an deiner stelle mal überprüfen ob hibernate tatsächlich die query an den server schickt. Falls du zugriff auf die mysql datenbank hast würde ich da mal in den logs nachsehen. oder wenn man es etwas technischer will, den network traffic angucken


----------



## KSG9|sebastian (20. Mai 2007)

Autoreconnect angeschalten? Verwendung von ner Datasource? Würd ich dir empfehlen...

Ich kenn das Problem aus folgendem Context:

- Hibernate baut Verbindung auf
- Anwendung läuft
- 20Uhr, die Anwendung wird nichtmehr benutzt, Hibernate hält sich die Verbindung
- MySQL killt die Verbindung zwecks inaktivität
- Morgens 8Uhr kommt ne Exception weil die Verbindung "gekillt" wurde

Datasource verwenden, MySQL umkonfigurieren oder alle Stunde einen DB-Zugriff mit Hibernate simulieren


----------



## nero30 (3. Jun 2007)

falls es noch jemanden interessiert, hab die Lösung für meine Version des Problems gefunden.
Es liegt an dem mysql-Server und zwar an der Variable wait_timeout. Sie ist standardmässig auf 28800 Minuten
also 8 Stunden eingestellt. Deswegen kam die Exception bei mir immer morgens, wenn meine Anwendung die ganze 
Nacht nicht auf die DB zugegriffen hatte. Setzen der Variable auf einen höheren Wert hat das Problem beseitig.

Gruß


----------

