JPA通过SQL脚本生成H2内存库schema成功但提示表不存在如何解决
问题原因及解决方案
核心原因(90%以上概率)
H2 内存数据库的默认配置规则是:当最后一个活跃连接关闭后,整个内存数据库会被自动销毁。
JPA 执行 schema 生成脚本的逻辑是单独申请一个连接执行 DDL 语句,执行完成后该连接就会被释放关闭,此时你创建的内存库已经被销毁。后续你创建 EntityManager 拿到的是全新的空内存数据库,自然会提示表不存在。
之前你用实体自动生成 schema 没有遇到这个问题,是因为 Hibernate 初始化实体元数据、创建 schema 的过程和后续业务操作复用了同一个连接池的活跃连接,没有触发数据库销毁的条件。
解决方法
修改 JDBC URL,添加DB_CLOSE_DELAY=-1参数,强制 H2 内存数据库在 JVM 进程退出前始终保留:
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
其他可能原因及排查方向
- 表名大小写敏感问题:如果导出的 SQL 脚本中表名使用了双引号包裹(比如
CREATE TABLE "xxx"),H2 会区分大小写,后续 SQL 语句中表名如果不带引号会被默认转为大写XXX,导致匹配失败。可以修改脚本去掉表名的双引号,或者在 JDBC URL 添加DATABASE_TO_UPPER=false参数关闭自动大写转换。 - DDL 执行未提交:如果你的 SQL 脚本中设置了手动提交事务,且没有加
COMMIT语句,会导致 schema 变更回滚。可以检查脚本末尾是否有提交语句,或者在 JDBC URL 添加AUTOCOMMIT=ON参数强制 DDL 自动提交。
内容的提问来源于stack exchange,提问作者AppleMoose
相关产品推荐
相关产品推荐

