
2009年6月12日
hibernate默認(rèn)連接池有一個(gè)問題,不會(huì)自動(dòng)檢測(cè)數(shù)據(jù)庫(kù)連接是否斷開,MYSQL數(shù)據(jù)庫(kù)一段時(shí)間(大約8小時(shí))沒有訪問就會(huì)斷開連接,連接池里的連接卻還是存在,下次訪問hibernate會(huì)繼續(xù)使用這個(gè)連接,導(dǎo)致數(shù)據(jù)庫(kù)連接異常。由于該問題需要在服務(wù)器長(zhǎng)時(shí)間運(yùn)行時(shí)才會(huì)出現(xiàn),所以在平時(shí)測(cè)試很難發(fā)現(xiàn)。
解決方法:
1.在連接參數(shù)中使用autoReconnect以后,第一次執(zhí)行失敗后會(huì)自動(dòng)重新連接。
2.通過把服務(wù)器上Mysql的"wait_timeout"屬性設(shè)置的高點(diǎn)。
3.不使用Hibernate內(nèi)置的連接池,改用C3P0連接池,這個(gè)連接池會(huì)自動(dòng)處理數(shù)據(jù)庫(kù)連接被關(guān)閉的情況。要使用C3P0很簡(jiǎn)單,先從Hibernate里把c3p0-0.8.3.jar復(fù)制到項(xiàng)目的lib目錄中,再在hibernate.properties里去掉hibernate.c3p0開頭的那些屬性的注釋(使用缺省值或自己需要的數(shù)值),這樣 Hibernate就會(huì)自動(dòng)使用C3P0代替內(nèi)置的連接池了。c3p0為open source的JDBC連接池,隨hibernate一起發(fā)布。c3p0連接池的配置非常簡(jiǎn)單,只需要在hibernate.cfg.xml里增加:
<!-- configuration pool -->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">100</property> <!-- seconds -->
<property name="c3p0.max_size">5</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">2</property>
<property name="c3p0.timeout">90</property> <!-- seconds -->
另外,還需要在CLASS_PATH里加上c3p0-x.x.x.jar文件(x.x.x為版本號(hào)),c3p0-x.x.x.jar文件隨hibernate一起發(fā)布,你可以在其lib目錄下找到該文件。
配置好之后,hibernate便會(huì)自動(dòng)使用c3p0的連接池:C3P0ConnectionProvider
項(xiàng)目中使用使用Hibernate作為持久層框架時(shí),如果數(shù)據(jù)庫(kù)由于某種原因需要改名,在修改數(shù)據(jù)庫(kù)連接后出現(xiàn)“could not execute query”異常,那么有可能是因?yàn)槟愕捻?xiàng)目里*.hbm.xml配置文件中的catalog屬性值還是原數(shù)據(jù)庫(kù)名,改成新數(shù)據(jù)庫(kù)名即可。或者干脆將catalog="..."屬性去掉,這樣就不會(huì)存在數(shù)據(jù)庫(kù)更名后無法執(zhí)行查詢的問題了。
這個(gè)問題雖然不是什么疑難雜癥,不過確實(shí)容易被忽略,我就被這個(gè)問題耽誤了好一會(huì)。