Spring Boot JPA saveAll无法保存全部CSV数据求助
Spring Boot中JpaRepository saveAll()仅保存部分数据的排查与解决
针对你遇到的CSV数据传入数量正确但仅部分保存到数据库的问题,可从以下几个方向排查:
1. 主键重复或冲突
- 问题原因:你的
StationsDAO使用CSV中的id作为数据库主键,若CSV中存在重复id,JPA的saveAll会执行更新操作(而非插入),最终数据库中实际新增的行数会少于传入的数量。 - 验证方式:打印传入的
stations列表的id去重后的数量,和原CSV总行数对比;或直接查询数据库中是否存在重复id的记录。 - 解决办法:确保CSV中
id字段唯一;若无需使用CSV的id作为数据库主键,可修改实体类主键策略为自增(比如添加@GeneratedValue(strategy = GenerationType.IDENTITY)注解)。
2. 数据校验或字段匹配失败
- 问题原因:
StationsDAO实体类可能存在校验注解(如@NotNull、@Size),或CSV中部分行的字段不符合数据库表结构要求(比如字符串长度超限、数值类型不匹配),导致JPA在保存时自动过滤无效数据,或隐性触发事务回滚。 - 验证方式:
- 开启JPA日志,添加配置:
logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE - 在转换
CsvStations到StationsDAO的过程中添加日志,打印每一行转换结果,排查是否有字段为空或格式错误。
- 开启JPA日志,添加配置:
- 解决办法:修复CSV中不符合规则的数据;调整实体类的校验注解或数据库表结构,确保匹配。
3. 事务未正常提交
- 问题原因:
ApplicationReadyEvent默认在事务上下文外执行,若保存过程中出现隐性异常(比如数据库字段约束违反),可能导致事务回滚但无明显报错。 - 验证方式:给
onStartApp方法或addStations方法添加@Transactional注解,强制开启事务,并查看日志中的异常信息。 - 解决办法:添加事务注解确保提交,示例:
@EventListener(ApplicationReadyEvent.class) @Transactional public void onStartApp() throws IOException { // 原代码逻辑不变 }
4. CSV转换的隐性错误
- 问题原因:虽然调试时看到列表数量正确,但部分行在转换为
StationsDAO时可能出现异常(比如Long.parseLong(s.getId())遇到非数字字符串),若未捕获异常可能导致部分数据丢失。 - 验证方式:在转换逻辑中添加异常捕获,打印错误行数据:
List<StationsDAO> stations = parseCSVToCSVStationsObject().stream() .map(s -> { try { return new StationsDAO( Long.parseLong(s.getId()), s.getName(), s.getAdress(), s.getKaupunki(), s.getKapasiteet(), s.getOperaattor(), s.getX(), s.getY() ); } catch (Exception e) { System.err.println("转换失败的行数据:" + s); e.printStackTrace(); throw e; } }) .collect(Collectors.toList()); - 解决办法:修复CSV中格式错误的字段,或添加异常处理逻辑跳过无效行。
5. 批量插入配置不全
- 问题原因:仅设置
spring.jpa.properties.hibernate.jdbc.batch_size=100不足以启用真正的批量插入,还需补充其他配置。 - 解决办法:添加以下配置到
application.properties:spring.jpa.properties.hibernate.jdbc.batch_size=100 spring.jpa.properties.hibernate.order_inserts=true spring.jpa.properties.hibernate.order_updates=true # 若使用MySQL,需添加该参数开启批量语句重写 spring.datasource.url=jdbc:mysql://localhost:3306/your_db?rewriteBatchedStatements=true
内容的提问来源于stack exchange,提问作者Erkan Isuf
相关产品推荐
相关产品推荐

