0

I have configured a Hibernate DAO in my application. Once a client ping that service, my server will use this DAO to connect to the database and retrieve some data.

This works fine for a couple of hours (or maybe one day), and then some thing goes wrong. I got exception like this:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 48,761,817 milliseconds ago. The last packet sent successfully to the server was 48,761,899 milliseconds ago. 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.

Once I redeploy my service, everything back to normal again. My codes is like this:

public class DeploymentInfoDAO {

private static SessionFactory factory = null;

private DeploymentInfo deploymentInfo = null;

private CheckLockStatusService checkLockStatusService = new CheckLockStatusService();

/**
 * Constructor
 */
public DeploymentInfoDAO() {

}

/**
 * Constructor
 * 
 * @param deploymentInfo
 */
public DeploymentInfoDAO(DeploymentInfo deploymentInfo) {
    this.deploymentInfo = deploymentInfo;
    // this.checkLockStatusService = new CheckLockStatusService();
}

/**
 * SELECT * FROM servicedashboard and converts the results into a list of
 * ServiceRow
 * 
 * @return
 */
public List<ServiceRow> getServiceRows() {
    List<ServiceRow> serviceRows = new ArrayList<ServiceRow>();
    if (factory == null){
        try {
            factory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Failed to create sessionFactory object." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }


    // mysql select test
    Session session = factory.openSession();
    Transaction tx = null;
    try {
        tx = session.beginTransaction();
        List<DeploymentInfo> deploymentInfos = session
                .createQuery(
                        "FROM com.test.hibernate.pojo.DeploymentInfo")
                .list();

        for (Iterator<DeploymentInfo> iterator = deploymentInfos.iterator(); iterator
                .hasNext();) {
            DeploymentInfo deploymentInfo = iterator.next();

            ServiceRow serviceRow = this
                    .convertToServiceRow(deploymentInfo);
            serviceRows.add(serviceRow);
        }
        tx.commit();
    } catch (HibernateException e) {

        if (tx != null)
            tx.rollback();
        e.printStackTrace();
    } finally {
        session.close();
    }
    return serviceRows;

}
}

Basically, every client call will create an DeploymentInfoDAO, and it will keep using the same static SessionFactory once it is created until it is not null.

It seems that after several hours, this SessionFactory became invalid but still not null.

What's the best practice to modify the code? And also, in the exception, it suggest using the Connector/J connection property 'autoReconnect=true' to avoid this problem, how to do this?

chrisTina
  • 2,298
  • 9
  • 40
  • 74

3 Answers3

2

Actually your server terminates the connection with MySQL after 8 hours of inactivity (8 hours is default) you can use autoReconnect=true in jdbc url

Syntax

jdbc:mysql://<host>:<port>/<db>?autoReconnect=true
Pulkit
  • 3,953
  • 6
  • 31
  • 55
  • I searched a while online and some one said: `using autoReconnect has a side effect about data consistency`. I am not sure whether this is the best practice. – chrisTina Apr 14 '16 at 13:34
  • the sideeffect occurs when application is not handling SQLException. when a connection is stale and you fire a query having autoReconnect will throw exception. You should catch that exception and can retry the query. Alternatively you can increase the wait_timeout at your MySQL server – Pulkit Apr 14 '16 at 13:38
0

Try to increase the wait timeout in your server or enable the auto reconnect in your JDBC URL.

javadev
  • 1,639
  • 2
  • 17
  • 35
0

Years ago I had the same problem. This is because MySQL close connection after a time of inactivity, it is not problem of your application.

One solution is create a dummy query (SELECT 1) and execute it every hour (or time that you estimate). This avoid MySQL closes connection.

Another it is increase the time limit of MySQL (This solution I don't like it, many times cannot modify database configuration for some reasons).

More information:

Terminating idle mysql connections

http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_wait_timeout

I hope this help you.

Community
  • 1
  • 1
Alberto
  • 745
  • 1
  • 6
  • 25