1. 程式人生 > >hibernate關於事務和sqlsession的幾個坑

hibernate關於事務和sqlsession的幾個坑

我們知道hibernate是ORM關係型資料庫。和資料庫互動的時候需要sqlsession,如果是儲存、更新、刪除操作的時候,還需要有事務。

在spring和hibernate整合的時候,事務都是有spring來處理。有的時候會遇到坑。

異常一:

Could not obtain transaction-synchronized Session for current thread

之前沒有問題的。因為修改了部分程式碼後出現了這個問題。

經過對比之後,發現正當時情況下:

在service層使用了類級別的事務。使用的是spring的@Transactional註解。

出現異常的時候,是事務註解被註釋掉了。

錯誤程式碼:

使用的是:Session session = getCurrentSession();這個方法。

經過查詢得到:

hibernate的sessionFactory中getCurrentSession()方法和OpenSession方法的區別:

所以,Could not obtain transaction-synchronized Session for current thread這個異常的原因是因為使用了 getCurrentSession();獲取session 而沒有使用@Transactional導致的。

擴充套件:

使用@Transactional預設只有當方法中丟擲unchecked的runtimeException時,才會進行回滾,丟擲需捕獲的Exception異常是不能進行回滾的

異常二:

A different object with the same identifier value was already associated with the session

錯誤截圖:

錯誤再現:

先查詢。如果存在,重新set指定欄位值之後,呼叫saveOrUpdateEntity的方法。就出現這個異常。

根據錯誤提示,可以分析得到:

在同一個session中,存在兩個相同的標識(如主鍵id),但是這兩個實體有不是相同的。

雖然使用了:

BaseNewinfoViewTotal entity =model.map(bean,BaseNewinfoViewTotal.class);

其實質也相當於是new了一個BaseNewinfoViewTotal 物件。然後重新賦值而已。

所以,兩個物件都有相同的主鍵ID,但是在記憶體中是兩個不同的物件。

這個時候解決方案:

採用session.merge (object c)代替session.save(object c),即可解決

歡迎關注凱哥公眾號:凱哥Java