凱哥Java 凱哥java
咱們知道hibernate是ORM關係型數據庫。和數據庫交互的時候須要sqlsession,若是是保存、更新、刪除操做的時候,還須要有事務。java
在spring和hibernate整合的時候,事務都是有spring來處理。有的時候會遇到坑。spring
異常一:sql
Could not obtain transaction-synchronized Session for current thread數據庫
以前沒有問題的。由於修改了部分代碼後出現了這個問題。session
通過對比以後,發現正當時狀況下:ide
在service層使用了類級別的事務。使用的是spring的@Transactional註解。hibernate
出現異常的時候,是事務註解被註釋掉了。3d
錯誤代碼:code
使用的是: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),便可解決