spring-boot
spring-boot copied to clipboard
Hibernate Schema Validation filter is not working after upgrading to Spring Boot v3.0.1
I am not sure if this is Spring or Hibernate issue, but after upgrading from Spring Boot 2.7.5 to 3.0.1 schema validation filter stopped working. Relevant properties:
spring.jpa.hibernate.ddl-auto: validate
spring.jpa.properties.hibernate.hbm2ddl.schema_filter_provider: [fully qualified name to custom schema filter provider]
Error Stack:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application_settings]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1130) ~[spring-context-6.0.3.jar:6.0.3]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:905) ~[spring-context-6.0.3.jar:6.0.3]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.3.jar:6.0.3]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.1.jar:3.0.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.1.jar:3.0.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.1.jar:3.0.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.1.jar:3.0.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.1.jar:3.0.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.1.jar:3.0.1]
at si.initialised.services.geo.GeoServiceApplication.main(GeoServiceApplication.java:12) ~[classes/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-3.0.1.jar:3.0.1]
Caused by: jakarta.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application_settings]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421) ~[spring-orm-6.0.3.jar:6.0.3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.3.jar:6.0.3]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1797) ~[spring-beans-6.0.3.jar:6.0.3]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1747) ~[spring-beans-6.0.3.jar:6.0.3]
... 19 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [application_settings]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:133) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:46) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:96) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:74) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:293) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at java.base/java.util.HashMap.forEach(HashMap.java:1421) ~[na:na]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:140) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:336) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:415) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1425) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66) ~[spring-orm-6.0.3.jar:6.0.3]
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.3.jar:6.0.3]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.3.jar:6.0.3]
... 23 common frames omitted
NOTE: application_settings table is not in included tables in custom schema validation filter.
If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
I don't have a Minimal Sample readily available, but I guess the problem is, that AbstractSchemaValidator
receives the correct schemaFilter
in constructor but then proceeds to never use it.
Instead it uses the SchemaFilter provided from ExecutionOptions
in the doValidation
method. Looks like a hibernate-core
problem to me..?
Thanks for trying to help, @mrohlof-protofy. It could well be a Hibernate problem but we won't be able to tell for sure without a sample from @Andrej988.
I am facing the same problem. Here you go.
Steps to reproduce
- Unzip,
-
mvn test
Actual behaviour
2.7.8: Test passes
3.0.2: Test fails because: Loading ApplicationContext fails because: Schema-validation: missing table [my_entity]
.
Expected behaviour "MyEntity" should be excluded from schema validation so that ApplicationContext can load properly.
#33832-minimal-example-springboot-3.0.2-fails.zip #33832-minimal-example-springboot-2.7.8-works.zip
The difference between both examples is:
a) spring-boot-starter-parent
version 2.7.8 -> 3.0.2
b) javax.persistence.*
-> jakarta.persistence.*
Thanks for the samples, @mrohlof-protofy. With them, I was able to see the hardcoded use of DefaultSchemaFilter.INSTANCE
that you've reported in https://hibernate.atlassian.net/browse/HBX-2476. This will need to be fixed in Hibernate.
Hello, any update on this ? it seems to continue to exist in spring 3.2.1 / Hibernate
@disk91 you should follow the updates on the hibernate issue Andy linked above.
I had a look at it, and nothing moved in 2023, that's a blocking bug in migration path. As no-one seems to act on Hibernate, is there a working bypass known ?
I am working with Quarkus whose version 3.6.5 uses Hibernate 6 and having problem with validating only one column. Everything else works just fine. All other columns within the same table works just fine, but a specific column cannot be matched with the column in database. I am using @Column
annotation on class member. Apart from that, I am using SnakeCase naming strategy. The complain is that Hibernate cannot find the column my_column where as @Column("myColumn")
is already present on the class member. I can also find the column "myColumn" in the database as is. If I create another column "my_column" in database, the error goes. But production database also uses "myColumn" convention and hence I cannot just change it.
@disk91 We have worked around it by abstracting a layer higher so the correct schema filter is used instead of the default one
Hibernate allows you to specify hibernate.schema_management_tool
instead
Then you can extend HibernateSchemaManagementTool
and override getSchemaValidator
to make sure your custom schema filter is used.
For us this meant also extending GroupedSchemaValidatorImpl
and overriding performValidation
and ensuring the configured SchemaFilter
(part of AbstractSchemaValidator
) is used instead of DefaultSchemaFilter.INSTANCE
Hope that helps
GroupedSchemaValidatorImpl
You're my hero... thanks to your hints I was able to get our schema validator up and running againg... Had to follow your path though including my own GroupdedShemaValidator with overriding performValidation...
Yeah, that DID help! Thanks!
@disk91 We have worked around it by abstracting a layer higher so the correct schema filter is used instead of the default one
Hibernate allows you to specify
hibernate.schema_management_tool
instead Then you can extendHibernateSchemaManagementTool
and overridegetSchemaValidator
to make sure your custom schema filter is used.For us this meant also extending
GroupedSchemaValidatorImpl
and overridingperformValidation
and ensuring the configuredSchemaFilter
(part ofAbstractSchemaValidator
) is used instead ofDefaultSchemaFilter.INSTANCE
Hope that helps
Thank you so much for replying, before I start to implement it, do you have an open source code implementing it to make sure I do it the right way ?
Take a look here: https://hibernate.atlassian.net/browse/HHH-17763 Seems to be fixed in 6.5 and 6.4.5 if I am correct...
Yes this has been fixed very recently although the bug has been there for over a year. This work around allowed us to get our Spring Boot 3 upgrade done while waiting for Hibernate to fix the bug (after 1 year we'd kinda lost hope it would be fixed). Hopefully we see Hibernate 6.4.5 in the next Spring Boot release