0

我将HibernateMySQLc3p0一起使用,当 MySQL 连接在 8 小时后(wait_timeout)到期时,Hibernate 无法重新连接,并且出现以下异常:

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:3249)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1403)
    at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
    at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
    at org.hibernate.loader.Loader.getResultSet(Loader.java:1812)
    at org.hibernate.loader.Loader.doQuery(Loader.java:697)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.doList(Loader.java:2232)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2129)
    at org.hibernate.loader.Loader.list(Loader.java:2124)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:401)
    at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
    at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1149)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)

这是hibernate.cfg:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb</property>
        <property name="hibernate.connection.username">username</property>
        <property name="hibernate.connection.password">password</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="hibernate.query.substitutions">true 1, false 0</property>

        <property name="hibernate.current_session_context_class">thread</property>

        <property name="hibernate.hbm2ddl.auto">validate</property>
        <property name="hibernate.connection.autocommit">false</property> 

        <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>        
        <property name="hibernate.c3p0.min_size">3</property>
        <property name="hibernate.c3p0.max_size">10</property>
        <property name="hibernate.c3p0.timeout">180</property>
        <property name="hibernate.c3po.max_idle_time">180</property> 
        <property name="hibernate.c3p0.idle_test_period">300</property>
        <property name="hibernate.c3p0.acquire_increment">3</property>

        <!-- My mappings here -->
    </session-factory>
</hibernate-configuration>

这是我的 c3p0.properties 文件:

c3p0.preferredTestQuery=SELECT 1

更新:

日志文件下方:

INFO - com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getPoolManager(462) | Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@6df9572
c [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@7eeb0844 [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetr
yDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassNam
e -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, debugUnreturnedConnectionStackTraces -> false, factoryClassLocation
 -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> jbnj238aq9q7lecas8ck|79b0d33c, idleConnectionTestPeriod -> 300, initialPoolSize -> 3, 
maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 180, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 10, maxStatements -> 0, maxState
mentsPerConnection -> 0, minPoolSize -> 3, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@8ed91d5 [ description -> null, driverClass -> null
, factoryClassLocation -> null, identityToken -> jbnj238aq9q7lecas8ck|445ead9d, jdbcUrl -> jdbc:mysql://localhost:3306/mydb, properties -> {user=******, p
assword=******, autocommit=false} ], preferredTestQuery -> SELECT 1, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false,
 unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false; userOverrides: {} ], dataSourceName -> null, factoryClassLocation -> null, iden
tityToken -> jbnj238aq9q7lecas8ck|26796e1c, numHelperThreads -> 
3 ]

任何提示表示赞赏。
谢谢

4

3 回答 3

1

我解决了这个问题:

设置c3p0属性时, 的值hibernate.c3p0.idle_test_period不得高于hibernate.c3p0.timeout. 所以在我的情况下:

<property name="hibernate.c3p0.timeout">180</property>
<property name="hibernate.c3p0.max_idle_time">180</property> 
<property name="hibernate.c3p0.idle_test_period">100</property>

解决它。

于 2010-08-12T19:48:16.517 回答
0

这是我抓到的部分。

the MySQL connection expires after 8 hours

如果您使用的是 c3p0,则不应发生这种情况。您应该建立一个新连接并将它们存储在池中。

如果您没有添加新连接或刷新您拥有的连接,您将超时。如果您多次尝试超时,请告诉 c3p0 重建/刷新连接池。

于 2010-08-11T18:37:49.103 回答
-1

愚蠢的问题:在您的 Hibernate 配置中,您有以下行:

<property name="hibernate.c3po.max_idle_time">180</property>

oinc3po应该0是. 这只是复制粘贴错误吗?丢失max_idle_time设置肯定会导致此问题。

编辑:查看c3p0 文档后,看起来正确的设置名称是hibernate.c3p0.timeout.

编辑 2:我刚刚查看了您的配置,您已经拥有hibernate.c3p0.timeout. 哦。因此,您可能可以忽略整个答案:-P。

于 2010-08-11T18:45:28.380 回答