在使用 Spring-Boot 进行 flyway 迁移后,Hibernate 无法验证内存中的 h2 数据库
Hibernate fails to validate in-memory h2 database after flyway migration using Spring-Boot
Hibernate 无法验证由 flyway 迁移创建的数据库架构。 (数据库迁移脚本是正确的)这是因为内存中的 H2 数据库吗?看起来 hibernate 连接到与 flyway 不同的数据库。
重现步骤:
使用 h2、flyway 和 jpa(休眠)创建 spring-boot 项目。
application.properties:
spring.datasource.url=jdbc:h2:mem:flyway_db
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.flyway.baseline-on-migrate=true
spring.flyway.url=jdbc:h2:mem:flyway_db
示例实体:
@Entity
@Table(name = "test_entity")
public class TestEntity {
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return description;
}
public void setDesc(final String desc) {
this.description = desc;
}
@Id
private int id;
private String description;
}
V1__init.sql 脚本:
CREATE TABLE test_entity
(
id INTEGER,
description VARCHAR(255),
PRIMARY KEY(id)
);
预期应用程序 运行 失败:完整日志:
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.6)
2022-05-20 12:53:54.920 INFO 10104 --- [ main] flyway_hibernate_h2.test.Application : Starting Application using Java 11.0.15 on cfe484487b08d045fbee329048f51788 with PID 10104 (/home/gitrow/eclipse-workspace-new/spring.flyway_hibernate_h2.test/target/classes started by gitrow in /home/gitrow/eclipse-workspace-new/spring.flyway_hibernate_h2.test)
2022-05-20 12:53:54.926 INFO 10104 --- [ main] flyway_hibernate_h2.test.Application : No active profile set, falling back to 1 default profile: "default"
2022-05-20 12:53:55.594 INFO 10104 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-05-20 12:53:55.613 INFO 10104 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 JPA repository interfaces.
2022-05-20 12:53:56.163 INFO 10104 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 8.0.5 by Redgate
2022-05-20 12:53:56.164 INFO 10104 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:h2:mem:flyway_db (H2 1.4)
2022-05-20 12:53:56.241 INFO 10104 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.027s)
2022-05-20 12:53:56.263 INFO 10104 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
2022-05-20 12:53:56.337 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
2022-05-20 12:53:56.344 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - init"
2022-05-20 12:53:56.381 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.054s)
2022-05-20 12:53:56.517 INFO 10104 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-05-20 12:53:56.558 INFO 10104 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.7.Final
2022-05-20 12:53:56.736 INFO 10104 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-05-20 12:53:56.832 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-05-20 12:53:56.854 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-05-20 12:53:56.874 INFO 10104 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2022-05-20 12:53:57.385 ERROR 10104 --- [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
2022-05-20 12:53:57.386 WARN 10104 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
2022-05-20 12:53:57.386 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-05-20 12:53:57.393 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2022-05-20 12:53:57.402 INFO 10104 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-05-20 12:53:57.427 ERROR 10104 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=14=](AbstractBeanFactory.java:335) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.6.jar:2.6.6]
at flyway_hibernate_h2.test.Application.main(Application.java:10) ~[classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.18.jar:5.3.18]
... 15 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:129) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:97) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:76) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:204) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:85) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.18.jar:5.3.18]
... 19 common frames omitted
我试过的方法:在内存数据库中显式命名,为数据源和 flyway 显式命名模式。
如问题下方的评论所述,可以通过从属性文件中删除 属性 spring.flyway.url
来解决问题。
如果未设置 属性,则 Spring Boot 将使用主 DataSource
配置 Flyway,或者如果存在,则使用注释的 DataSource
@FlywayDataSource
。 属性 spring.flyway.url
的存在是为了用具体的连接字符串覆盖这个选择过程。相关代码可以在 class FlywayAutoConfiguration
.
中找到
在 H2 的特殊情况下,覆盖连接字符串会导致 H2 数据库在事务后不会保持打开状态的问题,除非连接字符串包含告诉它这样做的标志。这解释了问题中的观察结果,即 Flyway 针对随后关闭的数据库运行,然后 Hibernate 连接到一个全新的 H2 实例。
这遵循 Spring 引导的通常模式及其 auto-configuration 的理念。 Auto-configuration 旨在工作 hands-off 并且仅由 class 路径上的事物触发。因此,对于它的许多功能,不需要 属性 或代码来启用它们。
同时,Spring Boot 只能使用合理的默认值或试探法 auto-configuration 应该在哪些情况下进行配置。因此,Spring Boot 带有扩展点和标志,如果 auto-configuration 没有做正确的事情,它们可以很容易地退出。 属性 spring.flyway.url
是这些标志之一。
Hibernate 无法验证由 flyway 迁移创建的数据库架构。 (数据库迁移脚本是正确的)这是因为内存中的 H2 数据库吗?看起来 hibernate 连接到与 flyway 不同的数据库。
重现步骤:
使用 h2、flyway 和 jpa(休眠)创建 spring-boot 项目。
application.properties:
spring.datasource.url=jdbc:h2:mem:flyway_db
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.flyway.baseline-on-migrate=true
spring.flyway.url=jdbc:h2:mem:flyway_db
示例实体:
@Entity
@Table(name = "test_entity")
public class TestEntity {
public int getId() {
return id;
}
public void setId(final int id) {
this.id = id;
}
public String getDesc() {
return description;
}
public void setDesc(final String desc) {
this.description = desc;
}
@Id
private int id;
private String description;
}
V1__init.sql 脚本:
CREATE TABLE test_entity
(
id INTEGER,
description VARCHAR(255),
PRIMARY KEY(id)
);
预期应用程序 运行 失败:完整日志:
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.6)
2022-05-20 12:53:54.920 INFO 10104 --- [ main] flyway_hibernate_h2.test.Application : Starting Application using Java 11.0.15 on cfe484487b08d045fbee329048f51788 with PID 10104 (/home/gitrow/eclipse-workspace-new/spring.flyway_hibernate_h2.test/target/classes started by gitrow in /home/gitrow/eclipse-workspace-new/spring.flyway_hibernate_h2.test)
2022-05-20 12:53:54.926 INFO 10104 --- [ main] flyway_hibernate_h2.test.Application : No active profile set, falling back to 1 default profile: "default"
2022-05-20 12:53:55.594 INFO 10104 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-05-20 12:53:55.613 INFO 10104 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 JPA repository interfaces.
2022-05-20 12:53:56.163 INFO 10104 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 8.0.5 by Redgate
2022-05-20 12:53:56.164 INFO 10104 --- [ main] o.f.c.i.database.base.BaseDatabaseType : Database: jdbc:h2:mem:flyway_db (H2 1.4)
2022-05-20 12:53:56.241 INFO 10104 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 1 migration (execution time 00:00.027s)
2022-05-20 12:53:56.263 INFO 10104 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
2022-05-20 12:53:56.337 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "PUBLIC": << Empty Schema >>
2022-05-20 12:53:56.344 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "PUBLIC" to version "1 - init"
2022-05-20 12:53:56.381 INFO 10104 --- [ main] o.f.core.internal.command.DbMigrate : Successfully applied 1 migration to schema "PUBLIC", now at version v1 (execution time 00:00.054s)
2022-05-20 12:53:56.517 INFO 10104 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-05-20 12:53:56.558 INFO 10104 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.7.Final
2022-05-20 12:53:56.736 INFO 10104 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-05-20 12:53:56.832 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2022-05-20 12:53:56.854 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2022-05-20 12:53:56.874 INFO 10104 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2022-05-20 12:53:57.385 ERROR 10104 --- [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
2022-05-20 12:53:57.386 WARN 10104 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
2022-05-20 12:53:57.386 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2022-05-20 12:53:57.393 INFO 10104 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2022-05-20 12:53:57.402 INFO 10104 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-05-20 12:53:57.427 ERROR 10104 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=14=](AbstractBeanFactory.java:335) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.6.jar:2.6.6]
at flyway_hibernate_h2.test.Application.main(Application.java:10) ~[classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.18.jar:5.3.18]
... 15 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:129) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:97) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:76) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:204) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:85) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498) ~[hibernate-core-5.6.7.Final.jar:5.6.7.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.18.jar:5.3.18]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.18.jar:5.3.18]
... 19 common frames omitted
我试过的方法:在内存数据库中显式命名,为数据源和 flyway 显式命名模式。
如问题下方的评论所述,可以通过从属性文件中删除 属性 spring.flyway.url
来解决问题。
如果未设置 属性,则 Spring Boot 将使用主 DataSource
配置 Flyway,或者如果存在,则使用注释的 DataSource
@FlywayDataSource
。 属性 spring.flyway.url
的存在是为了用具体的连接字符串覆盖这个选择过程。相关代码可以在 class FlywayAutoConfiguration
.
在 H2 的特殊情况下,覆盖连接字符串会导致 H2 数据库在事务后不会保持打开状态的问题,除非连接字符串包含告诉它这样做的标志。这解释了问题中的观察结果,即 Flyway 针对随后关闭的数据库运行,然后 Hibernate 连接到一个全新的 H2 实例。
这遵循 Spring 引导的通常模式及其 auto-configuration 的理念。 Auto-configuration 旨在工作 hands-off 并且仅由 class 路径上的事物触发。因此,对于它的许多功能,不需要 属性 或代码来启用它们。
同时,Spring Boot 只能使用合理的默认值或试探法 auto-configuration 应该在哪些情况下进行配置。因此,Spring Boot 带有扩展点和标志,如果 auto-configuration 没有做正确的事情,它们可以很容易地退出。 属性 spring.flyway.url
是这些标志之一。