hibernate 的evict 和clear
阿新 • • 發佈:2017-06-04
添加 當前 會話 線程 解決辦法 例子 ict hibernate ida
摘自百度知道:http://zhidao.baidu.com/question/63663640.html
問: 先創建一個Student,然後調用session.save方法,然後再調用evict方法把Student對象清除出緩存,再提交事務, 可是會報錯:Exception in thread "main" org.hibernate.AssertionFailure: possible nonthreadsafe access to session 但是如果我用的不是evict方法,而是clear方法用來清除緩存的話,程序沒有錯。 答: session.evict(obj),會把指定的緩沖對象進行清除 session.clear(),把緩沖區內的全部對象清除,但不包括操作中的對象 所以,hibernate執行的順序如下, (1)生成一個事務的對象,並標記當前的Session處於事務狀態(註:此時並未啟動數據庫級事務)。 (2)應用使用s.save保存對象,這個時候Session將這個對象放入entityEntries,用來標記對象已經 和當前的會話建立了關聯,由於應用對對象做了保存的操作,Session還要在insertions中登記應用 的這個插入行為(行為包括:對象引用、對象id、Session、持久化處理類)。 (3)s.evict將對象從s會話中拆離,這時s會從entityEntries中將這個對象移出。 (4)事務提交,需要將所有緩存flush入數據庫,Session啟動一個事務,並按照insert,update,……, delete的順序提交所有之前登記的操作(註意:所有insert執行完畢後才會執行update,這裏的特殊 處理也可能會將你的程序搞得一團糟,如需要控制操作的執行順序,要善於使用flush),現在對象不 在entityEntries中,但在執行insert的行為時只需要訪問insertions就足夠了,所以此時不會有任何 的異常。異常出現在插入後通知Session該對象已經插入完畢這個步驟上,這個步驟中需要將entityEntries 中對象的existsInDatabase標誌置為true,由於對象並不存在於entityEntries中,此時Hibernate就 認為insertions和entityEntries可能因為線程安全的問題產生了不同步(也不知道Hibernate的開發者 是否考慮到例子中的處理方式,如果沒有的話,這也許算是一個bug吧),於是一個net.sf.hibernate.AssertionFailure 就被拋出,程序終止 一般錯誤的認為s.save會立即的執行,而將對象過早的與Session拆離,造成了Session的insertions 和entityEntries中內容的不同步。所以我們在做此類操作時一定要清楚Hibernate什麽時候會將數據 flush入數據庫,在未flush之前不要將已進行操作的對象從Session上拆離。 解決辦法是在save之後,添加session.flush。
hibernate 的evict 和clear