Hibernate批量插入多条数据库记录仅成功插入1条如何解决
问题根因
- 全程复用同一个
Tx实例:你在循环外仅获取了1个Tx对象,循环内反复对同一个实例执行session.save()。Hibernate的save()方法仅对瞬时态对象(未关联Session、无有效主键标识)生成INSERT语句;当对象第一次执行save()后,会被关联到当前Session转为持久态,主键字段也会被赋值为数据库生成的值,后续再对同一个实例调用save(),只会触发UPDATE操作,不会生成新的INSERT。 - 实体类交由Spring容器管控不合理:你通过
applicationContext.getBean(Tx.class)获取实例,默认Spring管理的Bean是单例的,每次调用getBean都会返回同一个全局实例,无法生成新的独立对象。同时实体类作为数据载体,不需要被Spring容器管控,不需要添加@Component等Spring组件注解。 - ID字段类型不规范:你使用基本数据类型
int作为主键类型,默认值为0,Hibernate会将非0的ID判定为已存在的持久化标识,进一步阻断了新INSERT语句的生成,建议改为Integer包装类,符合JPA规范要求。
修复方案
- 移除
Tx类上的Spring组件注解,改为业务代码中手动新建实例 - 循环内每次创建独立的
Tx对象再执行保存操作 - 修正主键字段类型为
Integer
修复后代码示例:
Session session = sessionFactory.openSession(); session.beginTransaction(); IntStream.range(0, 100).forEach(index -> { // 每次循环新建独立实例 Tx tx = new Tx(); // 按需设置字段值 tx.setAaa("模板数据" + index); session.save(tx); }); session.getTransaction().commit(); session.close();
如果确实需要从Spring容器获取Tx实例,可给Tx类添加@Scope("prototype")注解声明为多例,每次getBean都会返回新实例,但该方案不推荐用于实体类场景。
内容的提问来源于stack exchange,提问作者mr_Stat1c
相关产品推荐
相关产品推荐

