Spring Boot与H2组合是否支持JPA属性javax.persistence.schema-generation.create-database-schemas?
问题根源
问题出在Hibernate执行DDL的顺序逻辑:配置javax.persistence.schema-generation.create-database-schemas=true后,Hibernate会先尝试执行删除表的DDL,再创建Schema,导致删除时Schema尚未存在,触发「Schema未找到」的错误。同时Spring Boot自动配置H2时的默认行为,也会引发数据库关闭警告。
解决方案1:保留Spring Boot自动配置,预初始化Schema
无需显式指定H2 URL,通过Hibernate初始化脚本提前创建Schema,适配自动配置逻辑:
- 在
src/main/resources下创建初始化脚本schema-h2.sql:
CREATE SCHEMA IF NOT EXISTS foo;
- 修改
application-local.properties配置:
# 覆盖Oracle数据源URL,让Spring Boot自动配置H2 spring.datasource.url= # 开启JPA Schema创建开关 spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true # 指定Hibernate启动时优先执行的Schema初始化脚本 spring.jpa.properties.hibernate.hbm2ddl.import_files=schema-h2.sql # 支持脚本中的多行SQL语句 spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor=org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
此方案会让Hibernate在执行表的drop/create操作前,先创建fooSchema,既解决了Schema不存在的问题,又完整保留Spring Boot对H2的自动配置(如默认用户名、密码、H2控制台启用等)。
解决方案2:显式指定H2 URL并解决关闭警告
如果必须使用H2的INIT参数初始化Schema,可通过禁用自动关闭钩子解决警告问题:
- 修改
application-local.properties:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS foo spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true
- 创建本地环境配置类,禁用自动关闭的Executor:
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration; import org.springframework.boot.autoconfigure.h2.H2Properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @ConditionalOnProperty(name = "spring.profiles.active", havingValue = "local") public class LocalH2Config { @Bean public H2ConsoleAutoConfiguration h2ConsoleAutoConfiguration(H2Properties properties) { return new H2ConsoleAutoConfiguration(properties) { @Override protected void registerShutdownHook() { // 空实现,不注册数据库关闭钩子 } }; } }
此方案既通过URL初始化了Schema,又避免了应用关闭时的「数据库已关闭」警告,同时保留H2控制台等自动配置特性。
内容的提问来源于stack exchange,提问作者EverGrowing
相关产品推荐
相关产品推荐

