hibernate关于事务和sqlsession的几个坑
2017-09-06 13:40
281 查看
我们知道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
在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
相关文章推荐
- 关于hibernate一级,二级缓存以及事务隔离机制。
- hibernate3第六章之性能优化相关几个问题_2事务隔离机制
- 关于spring 整合 hibernate 事务不回滚
- 关于事务(Transaction)的几个概念
- 今天总结:关于hibernate事务乐观锁和elipse启动tomcat报内存不足的最终解决方案
- 关于Hibernate框架源码中几个包的作用简要介绍
- 关于事务的几个概念介绍(转)
- 关于COPC后台配置的几个关键步骤及其事务代码
- 关于hibernate一级,二级缓存以及事务隔离机制。
- 关于JdbcTmplate和Hibernate共享事务的问题
- 关于hibernate事务和session的若干实践
- JavaEE框架——hibernate的使用(关于hibernate事务的必须开启的问题)
- hibernate3.6文档关于事务及并发策略的笔记
- 一些关于hibernate 与 spring 事务管理的问题
- 关于spring4和hibernate4整合,配置事务报“Cannot unwrap to requested type [javax.sql.DataSource]”错误的解决方法及心得
- hibernate的使用(关于hibernate事务的必须开启的问题)
- Caused by: java.sql.SQLSyntaxErrorException: ORA-00942: 表或视图不存在,分页等关于hibernate测试的几个问题
- 关于事务的几个概念介绍
- hibernate3.6文档关于事务及并发策略的笔记
- postgreSQL数据库关于事务的几个要点