2011-02-08 66 views
2

我有一段代碼使用休眠行爲意外;在嘗試了許多不同的調試策略之後,我想知道我對Hibernate會話/映射對象更新的理解是否不正確。這裏是簡化的場景:我有一個映射對象(MO),它是用id(long)和日期(日期/時間)定義的。 有一個主程序每60秒運行一次,根據日期/時間檢查需要處理的任何MO。主例程運行在單個線程中。這裏是僞代碼:訪問以前版本的數據對象的Hibernate查詢?

main() 
// open session 
// get current date/time 
// query all mapped objects where date/time field < current date/time 
// for each mapped object which matches { 
// updateObject (session, current date/time, mapped object) 
// } 
// flush session 
// close session 

updateObject(Session s, Date currentTime, MappedObject mo) 
// changes to mo object 
// add 1 day to currentTime and update date/time field in mo 
// transaction begin 
// update mo object 
// transaction committed 

未顯示:會話初始化工廠,異常處理例程

會話工廠配置了20(C3P0)的最大連接池大小。 默認設置正用於任何緩存。

問題

該查詢返回的MO其日期值在未來(即日期/時間字段>當前日期/時間)。根據對象監視,MO中的日期/時間字段的值是舊的先前值(不是重新計算的更新值),這會強制查詢將其提取並執行updateObject例程。

我假設更新通過直接監視數據庫驗證更新成功;此外,根據日誌,沒有任何事務異常被觸發。

此問題間歇性地發生 - 有時,它每天發生幾次,其他時間根本不發生。

平臺細節

Hibernate的版本:3.3.2.GA

C3P0版本:0.9.1

JRE版本:1.6.0_16

我的想法

我的第一個想法是編碼錯誤,但它確實似乎不是基地。我在想,如果以某種方式將對象的舊版本緩存在連接池中的某個Session對象中,並且出於某種原因,它會不時被拾取。

如果更新出現問題,我擔心更大的影響。

我現在使用的是舊版本的Hibernate--遷移到一個新版本可能會有挑戰性,但我想看看在走這條路線之前我是否誤解了某些東西。

任何建議或指示結果將不勝感激 - 先謝謝了!

更新

移動到Apache DBCP似乎已經解決了這個問題。如果再次觀察到問題,將會更新。

+0

無論您是否使用連接池,無論何時關閉會話(看起來您在做什麼),會話緩存都將被清除。這似乎更有可能與二級緩存或查詢緩存相關。這兩個默認情況下都沒有啓用,您是否配置了應用程序以使用二級緩存或查詢緩存? – Pace 2011-02-09 04:28:14

+0

@空間我看了二級緩存的文檔(http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html#performance-cache) - 這不是什麼我啓用了。同上查詢緩存選項(hibernate.cache.use_query_cache)。這很奇怪,因爲我懷疑緩存,但根據所有跡象,它應該關閉。鑑於間歇性,我想知道它是否可能是舊版本中的錯誤。 – slau 2011-02-09 17:09:12

回答

0

有兩兩件事你可以試試...

1)設置以下休眠特性把語句緩存關閉: -

<property name="hibernate.c3p0.max_statements">0</property> 

如果還是不行...

2)不要使用C3P0,請嘗試Apache DBCP以查看是否有相同的問題。它應該很容易換出。