Java 休眠无法打开连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3469319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:03:35  来源:igfitidea点击:

Hibernate cannot open connection

javahibernatespringjdbc

提问by DanInDC

I'm having trouble with hibernate not able to open a connection. I have a DAO:

我在休眠无法打开连接时遇到问题。我有一个 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;
    }
}

and then in a test case call findByQuery(1) 8 times, it works, but if I call a 9th time it fails with:

然后在测试用例中调用 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

This is what my hibernate properties look like:

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

<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>

If I change the release_mode to 'after_statement' (ala http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#transactions-connection-release) it will work, but I don't understand that and feel like that is just a band-aid for something bigger that I am doing wrong.

如果我将 release_mode 更改为“after_statement”(ala http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#transactions-connection-release)它会起作用,但我不明白那感觉就像是我做错了更大的事情的创可贴。

I've also tried to flush and close the this.getSession() with no luck either. I can see the close() gets called AFTER all of the calls to findByQuery(1) have completed.

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

This is on Hibernate 3.2.6, Spring 3.0 and MySQL 5.1. Let me know what more information I can provide.

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

采纳答案by axtavt

Javadoc for HibernateDaoSupport.getSession()says:

Javadoc forHibernateDaoSupport.getSession()说:

Note that this is not meant to be invoked from HibernateTemplate code but rather just in plain Hibernate code.Either rely on a thread-bound Session or use it in combination with releaseSession(org.hibernate.Session).

请注意,这并不意味着从 HibernateTemplate 代码中调用,而只是在普通的 Hibernate 代码中调用。要么依赖线程绑定会话,要么将它与 releaseSession(org.hibernate.Session) 结合使用。

So, the session obtained via getSession()should be released via releaseSession():

因此,通过获取的会话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);
    }        
}

But the better way to deal with session is to use a HibernateCallback:

但是处理会话的更好方法是使用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();    
        }
    });
}

回答by Oakscode

I solved the same problem by updating the mysql-connector-java-5.1.23-bin.jarfile.

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