Spring Boot集成H2数据库执行save操作数据无法存入问题排查求助
问题排查及解决方案
核心错误原因
- Controller层传参错误:你构造了包含完整
id、code、date属性的nextCode对象,但调用saveOrUpdate方法时传入的是前端传入的rqstCode对象。该对象仅code有值,id因为加了@JsonIgnore注解反序列化时为空,date属性完全未赋值,如果数据库date字段设置了非空约束,插入会直接失败;就算没有非空约束,存入的数据也和你预期构造的nextCode不一致,且返回给前端的id是你手动维护的idCounter生成的值,和数据库实际生成的主键不匹配。 - 主键生成逻辑冲突:实体类
id字段添加了@GeneratedValue(strategy = GenerationType.AUTO)注解,代表主键交由JPA自动生成,但你在业务代码中手动维护idCounter生成主键,两者逻辑完全冲突。 - 缺少SQL日志无法定位执行状态:现有配置没有开启Hibernate SQL打印,无法确认是否真的执行了INSERT语句、有没有参数错误或执行报错。
- H2库路径匹配问题:你配置的H2路径是相对路径
jdbc:h2:file:../snippets,如果启动项目的工作目录和你预期的不一致,会导致项目实际操作的库文件和你打开H2控制台连接的库不是同一个,自然看不到写入的数据。
修复步骤
- 修正Controller层存储逻辑:将构造好的
nextCode传入存储方法,而非前端传入的未补全属性的rqstCode
@PostMapping(value = "/api/code/new", produces = "application/json") public ResponseEntity<?> postCodeSnippet(@RequestBody Code rqstCode) { Code nextCode = new Code(idCounter++, rqstCode.getCode(), LoadDate.getLoadDate()); System.out.println(nextCode.getId()); codeList.add(nextCode); // 修正传参 codeService.saveOrUpdate(nextCode); return ResponseEntity.ok(new DTOCode(String.valueOf(nextCode.getId()))); }
- 统一主键生成逻辑:如果要使用JPA自动生成主键,删除手动维护的
idCounter,无需手动给id赋值,save执行后JPA会自动将数据库生成的主键回写到对象中:
@PostMapping(value = "/api/code/new", produces = "application/json") public ResponseEntity<?> postCodeSnippet(@RequestBody Code rqstCode) { Code nextCode = new Code(); nextCode.setCode(rqstCode.getCode()); nextCode.setDate(LoadDate.getLoadDate()); codeList.add(nextCode); codeService.saveOrUpdate(nextCode); // 直接获取JPA回写的数据库生成ID return ResponseEntity.ok(new DTOCode(String.valueOf(nextCode.getId()))); }
- 添加SQL打印配置:在
application.properties中添加以下配置,控制台会打印执行的SQL语句和参数绑定情况,方便排查后续问题:
spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true logging.level.org.hibernate.type.descriptor.sql.BasicBinder=trace
- 确认H2库连接一致:打开H2控制台时,确保填写的JDBC URL和配置文件中的
spring.datasource.url完全一致,避免连错库。
内容的提问来源于stack exchange,提问作者Staaankey
相关产品推荐
相关产品推荐

