Spring JUnit测试中H2 2.x版本持久化成功后查询报表不存在问题
Spring JUnit测试中H2 2.x内存库"Table not found"问题解决
问题根源
H2数据库2.x版本默认启用了区分大小写的标识符规则,会将未加引号的表名、列名自动转换为大写存储;而Hibernate生成的SQL使用小写表名进行操作,导致H2无法匹配到对应的表,抛出"Table not found"错误。这也是H2 1.4.x版本无此问题的原因——旧版本默认不区分标识符大小写。
解决方案
1. 修改H2 JDBC URL,兼容旧版大小写行为
在数据源URL中添加两个关键参数,让H2的标识符处理逻辑和1.4.x保持一致:
app.datasource.url = jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE
DATABASE_TO_LOWER=TRUE:强制将所有未加引号的标识符转换为小写存储CASE_INSENSITIVE_IDENTIFIERS=TRUE:查询时忽略标识符的大小写匹配
2. (可选)配置Hibernate全局引号标识符
如果修改URL后仍有问题,可以让Hibernate给所有表名、列名加上引号,避免H2自动转换大小写:
app.hibernate.globally_quoted_identifiers=true
此配置会让Hibernate生成的SQL类似insert into "my_entity" (...) values (...),确保表名完全匹配。
验证说明
从你的日志可以看到:
- Hibernate执行了
create table my_entity创建表,但H2 2.x默认会将其转为大写MY_ENTITY存储 - 后续插入操作Hibernate用小写
my_entity查询,导致H2找不到对应的大写表
添加上述URL参数后,H2会将表名转为小写存储,和Hibernate的SQL表名完全匹配,即可解决问题。
内容的提问来源于stack exchange,提问作者Vinars Patel




