hibernate 批量保存数据时存在唯一键unique值重复时报错的解决方式
来源:互联网 发布:中国新歌声网络主播 编辑:程序博客网 时间:2024/06/06 10:45
hibernate 批量保存数据时存在唯一键unique值重复时报错的解决方式 ( 主键策略为indentity时可用)
测试的数据库:mysql其中Teacher的主键策略分别为以下几种//Teacher1 -- native//Teacher2 -- hilo//Teacher3 -- indentity//Teacher4 -- increment4种主键策略的测试结果:主键方式仅native或indentity可以完成该操作
测试的项目文件:
点击进入项目资源链接页
在进行保存具有重复的唯一键值时出现以下错误:
错误代码:org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions WARN: SQL Error: 1062, SQLState: 23000
an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: null id in xxx entry (don’t flush the Session after an exception occurs)
本来以为解决不了了,通过后台程序实现这个功能:就是通过从数据库中取得已存在的数据对象集合与excel表获得的对象集合进行比较,如果存在则移除excel表取得的数据集合对象中的该对象(只保存未存在的数据场景,根据教工号判断)或者对该对象进行Oid赋值(保存未存在的数据、已存在的数据进行更新的场景),然后在for遍历这个excel的集合对象进行使用session.save()或者session.saveOrUpdate()方法。
后来发现junit中未报错,数据库表中却多出来一条记录,使用debug发现有一个实体类对象为null,进行了保存,然后发现自己模拟的对象集合的引用对象写错了,更正之后可以进行正确的保存操作了。经测试:在try代码块中未使用session.flush()两种方案均能解决错误问题,且数据能进行保存。
如果批量插入数据较多在一定数量时可以进行if(index % 20 == 0){session.flush(); session.clear();} ,只有方案一能够使用,方案二将会仍出现该错误。 以下就是我的解决方案,可以正常使用,不过目前博主对session.clear();有所疑惑,我觉得它当前场景(catch中)的作用是将该重复的实体对象从session中清除了。如果有正确的观点或其他见解,欢迎各位看官不吝指教~
解决方案一: 可以在操作一定数量时进行调用session.flush(); session.clear();
使用session.clear();
//session获取、事务开启for(Entity e: es){ try{ //新数据进行保存操作 session.save(e); }catch(ConstraintViolationException e){ //唯一键重复时 session.clear(); } }//最后session关闭、事务提交
解决方案二:不适合使用在一定数量时调用session.flush(); session.clear(); 的场景,否则仍会报出该错误
设置session.setFlushMode(FlushMode.NEVER);
//session获取、事务开启session.setFlushMode(FlushMode.NEVER);for(Entity e: es){ try{ //新数据进行保存操作 session.save(e); }catch(ConstraintViolationException e){ //唯一键重复时 }} //最后session关闭、事务提交
其中可在catch中进行重复数据的处理操作,比如更新。Entity e 是指实体类对象,es是指该实体类的集合。假设e指teacher,该实体类包括主键id,教工号是唯一键,备注等。
下面使用第一种进行介绍更新操作:
Session session = xxx.openSession(); //获取session,具体session怎么获取就不介绍了 Transaction transaction = session.beginTransaction(); //开启事务 for(Entity e: es){ //遍历该对象数据集合,具体数据就不模拟了 try{ session.save(e); }catch(ConstraintViolationException e){ //已存在的数据 session.clear(); Integer id = (Integer) session.createQuery("select id from Teacher where teacherNo = ?") .setString(0, e.getTeacherNo()).uniqueResult(); //首先获取该重复对象的oid e.setId(id); //设置游离对象 e.setMemo("重复唯一键"); session.update(e); session.flush(); //刷新缓存,同步更新数据库 } } transaction.commit(); //提交事务 session.close(); // 关闭Session
以上只是我找到的解决办法,且仅凭自己初步理解难免有错误,如果有更好见解或有所指教,欢迎各位指出。
0 0
- hibernate 批量保存数据时存在唯一键unique值重复时报错的解决方式
- hibernate 批量保存数据
- 实体重复保存时报错
- hibernate的unique与数据的重复添加
- Hibernate批量保存前台传递的EasyUI-datagrid数据
- Hibernate 批量插入数据,跳过重复数据
- Unique唯一值的前提是字段中不重复且空白值设为NULL
- 创建unique时,约束和索引有何区别。唯一约束和唯一索引区别,选项"忽略重复键"作用
- 创建unique时,约束和索引有何区别。唯一约束和唯一索引区别,选项"忽略重复键"作用
- Hibernate框架利用sessionFactory保存数据的两种方式
- mysql中的唯一键索引,插入重复数据直接报错的解决办法
- 使用Solr进行添加时报错的解决方式
- mac下 解决 Hibernate保存数据到mysql时的中文乱码问题
- 解决Hibernate保存数据到mysql时的中文乱码问题
- 关于唯一键(Unique)
- Spring管理Hibernate的批量保存
- 当表数据只有部份存在倾斜时,唯一值比例过高的列做直方图效果很差,不适合采用;
- Msql 批量数据判断唯一索引不存在做insert存在做update
- 类图
- 消息队列ActiveMQ+Spring整合
- springMVC学习笔记(一)-----springMVC原理
- Lua入门教程 1.准备知识
- 深入理解Android Context
- hibernate 批量保存数据时存在唯一键unique值重复时报错的解决方式
- failed to allocate XXXX bytes for committing reserved memory.
- php迭代器的基本例子
- c++上机实验7-项目2-最大公约和和最小公倍数
- 选项卡
- hadoop 之 mapreduce 特性
- service层AOP(基于注解的方法切入)
- linux的exec和source命令区别
- 《剑指offer》:[13]对几万公司员工年龄的排序算法