使用Hibernate时的CommunicationsException

时间:2016-04-14 13:15:26

标签: java mysql hibernate

我在我的应用程序中配置了Hibernate DAO。一旦客户端ping该服务,我的服务器将使用此DAO连接到数据库并检索一些数据。

这可以在几个小时(或者可能是一天)中正常工作,然后出现问题。我有这样的例外:

  

引起:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:   从服务器成功收到的最后一个数据包是48,761,817   几毫秒之前。成功发送到服务器的最后一个数据包是   48,761,899毫秒之前。比配置的服务器长   'wait_timeout'的值。你应该考虑到期和/或   在您的应用程序中使用前测试连接有效性,增加   服务器配置的客户端超时值,或使用   连接器/ J连接属性'autoReconnect = true'以避免这种情况   问题

重新部署服务后,一切恢复正常。我的代码是这样的:

公共类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;

}
}

基本上,每次客户来电都会创建一个DeploymentInfoDAO,一旦创建,它将继续使用相同的static SessionFactory,直到它不是null

似乎在几个小时后,此SessionFactory变为无效但仍然不为空。

修改代码的最佳做法是什么?而且,在例外中,它建议using the Connector/J connection property 'autoReconnect=true'避免这个问题,如何做到这一点?

3 个答案:

答案 0 :(得分:2)

实际上,您的服务器在闲置8小时后终止与MySQL的连接(默认为8小时) 您可以在jdbc url中使用autoReconnect=true

语法

jdbc:mysql://<host>:<port>/<db>?autoReconnect=true

答案 1 :(得分:0)

尝试增加服务器中的等待超时或在JDBC URL中启用自动重新连接。

答案 2 :(得分:0)

多年前我遇到了同样的问题。这是因为MySQL在一段时间不活动后关闭连接,这不是你的应用程序的问题。

一种解决方案是创建一个虚拟查询(SELECT 1)并每小时(或您估计的时间)执行它。这可以避免MySQL关闭连接。

另一个是增加MySQL的时间限制(这个解决方案我不喜欢它,很多时候由于某些原因无法修改数据库配置)。

更多信息:

Terminating idle mysql connections

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

我希望这对你有所帮助。