spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Hibernate Schema Validation filter is not working after upgrading to Spring Boot v3.0.1

Open Andrej988 opened this issue 2 years ago • 5 comments

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.

Andrej988 avatar Jan 14 '23 13:01 Andrej988

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.

mhalbritter avatar Jan 16 '23 09:01 mhalbritter

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.

spring-projects-issues avatar Jan 23 '23 09:01 spring-projects-issues

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..?

mrohlof-protofy avatar Jan 27 '23 10:01 mrohlof-protofy

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.

wilkinsona avatar Jan 27 '23 10:01 wilkinsona

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.*

mrohlof-protofy avatar Jan 27 '23 11:01 mrohlof-protofy

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.

wilkinsona avatar Feb 22 '23 20:02 wilkinsona

Hello, any update on this ? it seems to continue to exist in spring 3.2.1 / Hibernate

disk91 avatar Jan 11 '24 13:01 disk91

@disk91 you should follow the updates on the hibernate issue Andy linked above.

bclozel avatar Jan 11 '24 13:01 bclozel

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 ?

disk91 avatar Jan 11 '24 13:01 disk91

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.

mimranfaruqi avatar Jan 15 '24 20:01 mimranfaruqi

@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

instagibb avatar Feb 13 '24 02:02 instagibb

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!

SteMoeller avatar Mar 01 '24 10:03 SteMoeller

@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

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 ?

disk91 avatar Mar 10 '24 12:03 disk91

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...

SteMoeller avatar Mar 10 '24 16:03 SteMoeller

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

instagibb avatar Mar 11 '24 22:03 instagibb