a different object with the same identifier value was already associated with the session,samedifferentblog
這個文章的方案符合我的要求,記錄在此:
觸發情境,解決方案:
1. show業務操作,開啟一個session ,從中查出一些實體,這時某個實體是存在於session中的持久化對象。通過商務邏輯將此實體用於頁面展示。此時這個session並未關閉。
2. 這時執行一步save商務邏輯,將上一步獲得的實體id傳回後台 。這時通過new的方式建立了一個臨時對象,並且我將傳回的id作為主鍵賦值給了臨時對象。然後調用了session.save(obj); 方法 。。。拋出異常。
原因很簡單,session中有2個oid一樣的對象,hibernate不知道該讓哪個持久化到庫裡。當時解決思路也很清晰,直接clear();清空一下 session緩衝不就Ok了。但是clear打擊面太廣了(慎用!)。其他一些“無辜”對象也被殺掉,導致其他業務無法進行了。
後來在session中發現一個evict方法,“定點清除”對象緩衝。這下就好了,先用傳回來的id用其實這裡用load方法也行反正都是從緩衝中載入)獲得session裡的持久化實體,然後殺掉,再儲存臨時實體。沒問題了。
原文地址:http://www.cnblogs.com/linjiqin/p/3531374.html
由於我的session是封裝的,本身沒有get,evict方法,所以先調用出被他封裝的session,而後就能使用這兩個方法了.
HBSession sess = HBUtil.getHBSession();
Query queryUser = sess.createQuery(From User where name=:name);
queryUser.setString("name","測試人員");
List<User> UserList = queryUser.list();
...
...
...//這裡是使用的過程
//接下來進行清理
for(int i=0;i<UserList.size();i++){
//sess.getSession()是擷取被封裝的session,因為我的sess本身沒有get(xxxx,xxx),evict(Object) 方法
//自行百度session.get方法的使用方式
Object tempUser= sess.getSession().get(User.class, UserList.get(i).getKey());
//把取到的對象從sess緩衝中清理出去
sess.getSession().evict(tempUser);
}