1. 程式人生 > >hibernate session中clear、evict、flush方法的區別

hibernate session中clear、evict、flush方法的區別

           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。