简体   繁体   English

使用Hibernate和JDBC关闭连接

[英]Connection close with Hibernate and JDBC

I have following problem. 我有以下问题。 I am writing a desktop java application with database on server. 我正在用服务器上的数据库编写桌面Java应用程序。 I also use hibernate. 我也使用休眠模式。 When I run application everything works fine and I have correct connection with database, but after few minutes when I do some operations on database I get following error: 当我运行应用程序时,一切正常,并且与数据库的连接正确,但是几分钟后,当我对数据库进行一些操作时,出现以下错误:

Exception thrown: 
Class: model.MainRepository

    Stack Trace:
    org.hibernate.TransactionException: JDBC begin transaction failed: 
        at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.begin(AbstractLogicalConnectionImplementor.java:72)
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:238)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:213)
        at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1443)
        at model.MainRepository.addTrainingToUser(MainRepository.java:151)
        at model.Parser.parseFilesWatch(Parser.java:85)
        at controller.UploadDataController$1.call(UploadDataController.java:148)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    Last packet sent to the server was 11 ms ago.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1074)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2985)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2871)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3414)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2536)
        at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4874)
        at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.begin(AbstractLogicalConnectionImplementor.java:67)
        ... 10 more
    Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
        at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2431)
        at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2882)
        ... 17 more

    Exception thrown: 
    Class: model.MainRepository
    Stack Trace:
    org.hibernate.TransactionException: JDBC begin transaction failed: 
        at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.begin(AbstractLogicalConnectionImplementor.java:72)
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:238)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:213)
        at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
        at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1443)
        at model.MainRepository.sendTrainingDetails(MainRepository.java:184)
        at model.Parser.parseFilesWatch(Parser.java:94)
        at controller.UploadDataController$1.call(UploadDataController.java:148)
        at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.Util.getInstance(Util.java:381)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
        at com.mysql.jdbc.ConnectionImpl.getMutex(ConnectionImpl.java:3018)
        at com.mysql.jdbc.ConnectionImpl.setAutoCommit(ConnectionImpl.java:4827)
        at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.begin(AbstractLogicalConnectionImplementor.java:67)
        ... 10 more

Here is my hibernate.cfg.xml file: 这是我的hibernate.cfg.xml文件:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.pool_size">1</property>
        <property name="hibernate.connection.url">jdbc:mysql://sql.aaa.nazwa.pl:1111/aaaa</property>
        <property name="hibernate.connection.username">aaa</property>
        <property name="hibernate.connection.password">bbb</property>
        <property name="show_sql">true</property>
        <mapping resource="model/models.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

HibernateUtil.java HibernateUtil.java

package model;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Created by Piotr on 2015-10-11.
 */
public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return 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;
    }

    public static void shutdown() {
        // Close caches and connection pools
        getSessionFactory().close();
    }
}

And sample operation on database: 并对数据库进行示例操作:

public void addUser(User user) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.save(user);
            tx.commit();
        } catch (Exception e) {
            if (tx != null) tx.rollback();
            Logger.saveToLogFile(e, this.getClass().getName());
        } finally {
            session.close();
        }
    }

Ok, I have solved this problem. 好的,我已经解决了这个问题。 Parameter called 'idleConnectionTestPeriod' in c3p0 should be set. 应该设置c3p0中名为“ idleConnectionTestPeriod”的参数。 From documentation "If this is a number greater than 0, c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds." 来自文档"If this is a number greater than 0, c3p0 will test all idle, pooled but unchecked-out connections, every this number of seconds."

This most likely comes as a result of using the built-in Hibernate connection pool that is currently unsupported as specified in the documentation and also you set having a size of 1. 这很可能是由于使用了文档中指定的当前不支持的内置Hibernate连接池,并且您设置的大小为1。

Try using a connection pool like Hikari or c3p0 again as per documentation. 根据文档尝试再次使用连接池,例如Hikaric3p0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM