REST服务嵌入H2数据库后POST请求异常,GET返回空数组求助
嵌入式H2数据库REST服务POST无报错但GET返回空的排查与解决
嘿,我之前做Spring Boot嵌入H2的REST服务时也碰到过一模一样的问题——POST发出去没报错,但GET回来就是空数组。不用急着删库重启,咱们一步步排查解决:
1. 先检查H2的持久化配置是否踩坑
嵌入式H2默认是纯内存模式(jdbc:h2:mem:testdb),这种模式下每个请求的数据库会话是隔离的,你用Postman发POST的会话和GET的会话可能不是同一个,导致看不到数据;而且重启项目后数据直接清空。
赶紧核对application.properties里的数据源配置:
# 错误:纯内存模式,会话隔离+重启丢数据 # spring.datasource.url=jdbc:h2:mem:testdb # 正确:持久化到本地文件,所有会话共享数据,重启也保留 spring.datasource.url=jdbc:h2:file:./local-data/my-h2-db;DB_CLOSE_ON_EXIT=FALSE spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=
重点是DB_CLOSE_ON_EXIT=FALSE,它能防止JVM退出时自动关闭数据库导致数据丢失。
2. 排查事务是否悄悄回滚
很多时候POST没报错,但数据根本没写入——大概率是事务没提交或者被自动回滚了:
- 看看你的Service层保存方法有没有加
@Transactional注解?如果是private方法,Spring的事务代理会失效,导致数据无法提交。比如:// 错误示范:private方法不会被Spring代理,事务不生效 private void saveUser(User user) { userRepository.save(user); } // 正确操作:public方法加@Transactional @Transactional public void saveUser(User user) { userRepository.save(user); } - 有没有在代码里吞了异常?比如try-catch里捕获了异常但没抛出,Spring会自动回滚事务,数据也就不会写入数据库。
3. 用H2控制台直接验证数据库真实数据
别光看GET返回的结果,直接去H2控制台查数据库里到底有没有数据:
- 先在配置里开启控制台:
spring.h2.console.enabled=true spring.h2.console.path=/h2-console - 启动项目后访问
http://localhost:8080/h2-console,用和application.properties里完全一致的URL、用户名密码登录,直接查询你的表:- 如果表里有数据:问题出在GET接口的查询逻辑(比如Repository方法写错过滤条件、实体类字段映射不匹配)
- 如果表里没数据:肯定是POST的写入环节出问题了(回到前面的配置和事务排查)
4. 检查GET接口的查询逻辑
如果H2控制台里有数据,但GET返回空数组:
- 核对Repository的查询方法是不是加了错误的过滤条件?比如本来要查全部,结果写了
findByStatus(1)但你存的数据status是0。 - 检查实体类的字段映射:比如实体类里的
userName,数据库里的列是username,没加@Column(name = "username")的话,ORM框架会查不到数据。
必须删库重启吗?完全不用!
给你几个灵活的解决方案:
- 切换持久化模式:把内存模式改成文件模式(前面的配置),以后重启项目数据也不会丢失。
- 清空现有数据:如果要重置数据,不用删文件,直接在H2控制台执行SQL:
TRUNCATE TABLE your_table_name; -- 清空表数据 -- 或者直接删表重建 DROP TABLE your_table_name; - 自动初始化数据:可以在项目启动时自动执行SQL脚本创建表、插入测试数据:
spring.sql.init.mode=always spring.sql.init.schema-locations=classpath:schema.sql spring.sql.init.data-locations=classpath:data.sql
内容的提问来源于stack exchange,提问作者Lambda
相关产品推荐
相关产品推荐

