H2文件数据库重启时Hibernate重复建表报错求助
本地测试时我的application-local.yml配置如下:
spring: datasource: url: jdbc:h2:file:./data/db-test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE username: dbtest password: dbtest driver-class-name: org.h2.Driver jpa: show-sql: true generate-ddl: false properties: # 解决createclob方法报错问题 hibernate.temp.use_jdbc_metadata_defaults : false hibernate: dialect: org.hibernate.dialect.H2Dialect hibernate: ddl-auto: update h2: console: enabled: true path: /public/h2-console liquibase: enabled: false
首次启动服务器时,Hibernate成功创建表并生成数据库文件。但重启服务器时,Hibernate仍尝试创建已存在的表和约束,导致报错。我已将ddl-auto设为update,且尝试将generate-ddl设为false,问题依旧。
报错日志示例:
Hibernate: create table myTable (id bigint not null, ..., primary key (id)) 15:59:49.252 [restartedMain] WARN o.h.t.s.i.ExceptionHandlerLoggedImpl - GenerationTarget encountered exception accepting command : Error executing DDL "create table myTable (id bigint not null, ..., primary key (id))" via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table myTable(id bigint not null, ..., primary key (id))" via JDBC Statement at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:562) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:507) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:277) at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:71) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:318)
请问我哪里配置出错了?
问题根源及解决方案
Hibernate方言配置层级错误
你在jpa.properties下嵌套了hibernate.dialect,但Spring Boot中Hibernate方言的正确配置位置应该是jpa.properties.hibernate.dialect(平级而非嵌套)。当前嵌套写法会导致Hibernate无法正确识别方言,进而无法准确判断H2数据库中已存在的表结构,重启时重复执行建表语句。修正后的配置片段:
jpa: properties: hibernate.temp.use_jdbc_metadata_defaults: false hibernate.dialect: org.hibernate.dialect.H2Dialect # 改为平级配置禁用JDBC元数据的副作用
你设置了hibernate.temp.use_jdbc_metadata_defaults: false,这会让Hibernate无法通过JDBC获取数据库元数据,导致它无法确认表是否已存在。如果你的项目不需要这个配置来解决CLOB问题,可以尝试移除它;如果必须保留,确保方言配置正确,同时检查H2数据库文件的读写权限(确保重启时能正确读取已生成的数据库文件)。确认H2数据库文件路径
检查./data/db-test路径下是否生成了完整的H2数据库文件(包括.mv.db、.trace.db等),重启时应用是否能访问到这个路径。如果路径权限不足或文件损坏,Hibernate会认为数据库为空,重新执行建表操作。Spring Boot版本兼容性
部分旧版Spring Boot与Hibernate的组合可能存在update模式的识别问题,若上述配置修正后仍无效,可以尝试升级Spring Boot到稳定版本。
内容的提问来源于stack exchange,提问作者phildeg31

