hibernate关于事务和sqlsession的几个坑

hibernate关于事务和sqlsession的几个坑

凯哥Java 凯哥java
咱们知道hibernate是ORM关系型数据库。和数据库交互的时候须要sqlsession,若是是保存、更新、删除操做的时候,还须要有事务。java

在spring和hibernate整合的时候,事务都是有spring来处理。有的时候会遇到坑。spring

异常一:sql

Could not obtain transaction-synchronized Session for current thread数据库

hibernate关于事务和sqlsession的几个坑

以前没有问题的。由于修改了部分代码后出现了这个问题。session

通过对比以后,发现正当时状况下:ide

hibernate关于事务和sqlsession的几个坑

在service层使用了类级别的事务。使用的是spring的@Transactional注解。hibernate

出现异常的时候,是事务注解被注释掉了。3d

错误代码:code

hibernate关于事务和sqlsession的几个坑

使用的是:Session session = getCurrentSession();这个方法。对象

通过查询获得:

hibernate的sessionFactory中getCurrentSession()方法和OpenSession方法的区别:

hibernate关于事务和sqlsession的几个坑

因此,Could not obtain transaction-synchronized Session for current thread这个异常的缘由是由于使用了 getCurrentSession();获取session 而没有使用@Transactional致使的。

扩展:

使用@Transactional默认只有当方法中抛出unchecked的runtimeException时,才会进行回滚,抛出需捕获的Exception异常是不能进行回滚的
hibernate关于事务和sqlsession的几个坑
hibernate关于事务和sqlsession的几个坑

hibernate关于事务和sqlsession的几个坑

异常二:

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

错误截图:
hibernate关于事务和sqlsession的几个坑

错误再现:

hibernate关于事务和sqlsession的几个坑

先查询。若是存在,从新set指定字段值以后,调用saveOrUpdateEntity的方法。就出现这个异常。

根据错误提示,能够分析获得:

在同一个session中,存在两个相同的标识(如主键id),可是这两个实体有不是相同的。

虽然使用了:

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

其实质也至关因而new了一个BaseNewinfoViewTotal 对象。而后从新赋值而已。

因此,两个对象都有相同的主键ID,可是在内存中是两个不一样的对象。

这个时候解决方案:

采用session.merge (object c)代替session.save(object c),便可解决
hibernate关于事务和sqlsession的几个坑