【问题标题】:Hibernate cannot open connection休眠无法打开连接
【发布时间】:2011-03-29 00:18:55
【问题描述】:

我遇到了休眠无法打开连接的问题。我有一个 DAO:

public class MyDao extends HibernateDaoSupport
{
    DataSource dataSource;

    public void setDataSource(DataSource dataSource)
    {
        this.dataSource = dataSource;
    }

    public MyPOJO findByQuery(int hour)
    {
        Query query = this.getSession().createSQLQuery(
        "SELECT * FROM MyPOJO WHERE someDate >= DATE_SUB(now(), INTERVAL ? HOUR)")
        .addEntity(MyPOJO.class);

        List<MyPOJO> results = query.setInteger(0, hours).list();

        return results;
    }
}

然后在测试用例中调用 findByQuery(1) 8 次,它可以工作,但如果我第 9 次调用它会失败:

org.hibernate.exception.GenericJDBCException: Cannot open connection
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:103)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:91)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:29)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:426)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1547)
at org.hibernate.loader.Loader.doQuery(Loader.java:673)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2213)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
Caused by: org.apache.commons.dbcp.SQLNestedException: Could not retrieve connection info from pool
at org.apache.commons.dbcp.datasources.SharedPoolDataSource.getPooledConnectionAndInfo(SharedPoolDataSource.java:169)
at org.apache.commons.dbcp.datasources.InstanceKeyDataSource.getConnection(InstanceKeyDataSource.java:631)
at org.apache.commons.dbcp.datasources.InstanceKeyDataSource.getConnection(InstanceKeyDataSource.java:615)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
... 35 more
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:827)
at org.apache.commons.dbcp.datasources.SharedPoolDataSource.getPooledConnectionAndInfo(SharedPoolDataSource.java:165)
... 39 more

这是我的休眠属性的样子:

<property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQL5Dialect
            </prop>
            <prop key="hibernate.current_session_context_class">
                thread
            </prop>
            <prop key="hibernate.format_sql">false</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.use_sql_comments">false</prop>
            <prop key="hibernate.jdbc.use_get_generated_keys">true</prop>
            <prop key="hibernate.cache.use_second_level_cache">true</prop>
            <prop key="hibernate.cache.provider_class">
                org.hibernate.cache.EhCacheProvider
            </prop>
            <prop key="hibernate.connection.release_mode">auto</prop>
        </props>
    </property>

如果我将 release_mode 更改为 'after_statement' (ala http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#transactions-connection-release) 它将起作用,但我不明白这一点,并且觉得这只是我做错的更大事情的创可贴。

我也尝试过刷新和关闭 this.getSession() 也没有运气。我可以看到在对 findByQuery(1) 的所有调用都完成后调用了 close()。

这是在 Hibernate 3.2.6、Spring 3.0 和 MySQL 5.1 上。 让我知道我可以提供哪些更多信息。

【问题讨论】:

  • 不是有Caused by的异常吗?

标签: java hibernate spring jdbc


【解决方案1】:

Javadoc for HibernateDaoSupport.getSession() 说:

请注意,这并不意味着 从 HibernateTemplate 代码调用 而只是简单的休眠 代码。 要么依赖线程绑定 会话或结合使用它 releaseSession(org.hibernate.Session)。

那么,通过getSession()获得的会话应该通过releaseSession()释放:

public MyPOJO findByQuery(int hour) 
{ 
    Session s = null;
    try {
        s = this.getSession();
        Query query = s.createSQLQuery( 
        "SELECT * FROM MyPOJO WHERE someDate >= DATE_SUB(now(), INTERVAL ? HOUR)") 
        .addEntity(MyPOJO.class); 

        List<MyPOJO> results = query.setInteger(0, hours).list(); 

        return results; 
    } finally {
        if (s != null) this.releaseSession(s);
    }        
}

但处理会话的更好方法是使用HibernateCallback

public MyPOJO findByQuery(int hour) 
{ 
    return this.getHibernateTemplate().executeFind(new HibernateCallback<List<MyPOJO>>() {
        List<MyPOJO> doInHibernate(org.hibernate.Session session) {
            Query query = session.createSQLQuery(    
                "SELECT * FROM MyPOJO WHERE someDate >= DATE_SUB(now(), INTERVAL ? HOUR)")    
                    .addEntity(MyPOJO.class);    
            return query.setInteger(0, hours).list();    
        }
    });
}

【讨论】:

  • 啊!我一直在寻找一种通过 getHibernateTemplate() 来实现它的方法。非常感谢。
  • 非常感谢!我永远不会明白为什么我的应用程序在使用getSession()..时每 10 分钟就会失败一次。
【解决方案2】:

我通过更新mysql-connector-java-5.1.23-bin.jar 文件解决了同样的问题。

【讨论】:

    猜你喜欢
    • 2016-07-04
    • 2013-08-09
    • 1970-01-01
    • 2013-03-09
    • 2018-08-19
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2011-06-13
    相关资源
    最近更新 更多