2015-09-04 104 views
1

我有一個使用Hibernate來管理SQL連接的獨立Java應用程序。我使用MySQL數據庫,並確保當main()方法退出時所有會話都關閉。Hibernate/C3P0沒有正確關閉MySQL連接(mysql.err上的異常連接)

我的代碼是這樣的:

public static void main(String[] args) { 

    logger.info("Starting app"); 
    App instance = new App(); 
    try { 
     instance.run(); 
    } catch (Exception e) { 
     logger.error("failed to complete run", e); 
    } finally { 
     HibernateUtil.closeCurrentSession(); 
    } 
    logger.info("Finished run"); 
} 

現在,每當這個主要方法退出,我看到一個登錄我的SQL錯誤日誌說:[Warning] Aborted connection 41533470 to db: 'user' user: 'some_user' host: 'some_ip_address_here' (Got an error reading communication packets)

這是否意味着MySQL的手動殺死它?如果是這樣,我該如何優雅地關閉我的MySQL連接?如果我能夠正確回想我的Hibernate,關閉會話就會把它們放回會話池中......我不知道如何完全告訴Hibernate釋放它與MySQL的連接。

編輯:我正在使用C3P0這一個 - 抱歉忘了提前。我的連接關閉,但這只是我的mysql.err日誌上的[Warning]錯誤。我不喜歡看到這些類型的警告,因爲顯然有錯誤。

+1

[Hibernate連接可能重複,即使使用C3P0 +顯式session.close()也不會關閉(http://stackoverflow.com/questions/9755523/hibernate-connections-are-not-closed-even-with- c3p0-explicit-session-close) – Andreas

+0

這篇文章中沒有任何內容會說他正在使用C3P0。 – peterh

+0

以下解決方案對我有所幫助。 [在此輸入鏈接描述](http://stackoverflow.com/questions/40758569/all-used-connections-in-pool-are-sleepy-new-connections-are-created/40861706#40861706) – Rajas

回答

0

Apparently, this is actually a bug from Hibernate.

我補充說,關閉我的HibernateUtil的C3P0ConnectionProvider靜態地訪問,以及另一種方法。

SessionFactoryImpl impl = (SessionFactoryImpl) sessionFactory; 
C3P0ConnectionProvider provider = (C3P0ConnectionProvider) impl.getConnectionProvider(); 
provider.close(); 

之後,我再也沒有看到那些討厭的警告。

-1

run()方法中控制代碼中的Hibernate會話。

查看javadoc的Session爲例。如果你使用Google,可能會有很多其他Hibernate會話控制的例子。

如果對HibernateUtil.closeCurrentSession()的調用有所作爲,那麼run()方法本身沒有正確清理。

+0

控制?你什麼意思?手動關閉會話?因爲這就是'HibernateUtil.closeCurrentSession()'所做的。 – mpmp

+0

因爲我不知道你的'run()'方法在做什麼或者你的HibernateUtil是如何編碼的,所以很難說這裏有什麼問題。可能的是,您不*關閉數據庫連接,所以當虛擬機退出時,連接會硬中止。 – Andreas

+0

HibernateUtil有一個ThreadLocal 對象,用於保存會話。在第一次調用HibernateUtil.getCurrentSession()時,會話對象被放入該ThreadLocal對象中。每當我HibernateUtil.getCurrentSession(),我檢查是否有可用的打開會話,如果沒有,我創建一個。 run()方法的功能是隻查詢和刪除數據庫中的條目。 HibernateUtil.closeCurrentSession()只是關閉在ThreadLocal對象中存在的會話(如果它存在的話)。 在這種情況下,如何手動關閉數據庫連接? – mpmp