spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.56k stars 40.55k forks source link

Spring 3.x.x doesn't create schemas #35938

Closed j2yemi closed 1 year ago

j2yemi commented 1 year ago

Spring 2.7.2 creates schema if not found in the database (using postgresql). All i did was specifying schema ="foo" in the entity and specfying spring.jpa.properties.hibernate.hbm2dll.create_namespaces=true in the config file and of course these spring.jpa.hibernate.ddl-auto= update spring.jpa.generate-ddl=true

I started a new project on spring 3.1.0 and with the settings above the schemas not created. Forces me to manually create the schema from the database.

Is this change intentional or the the config settings changed?

wilkinsona commented 1 year ago

Schema creation using spring.jpa.hibernate.ddl-auto is a Hibernate feature and should continue to work with Spring Boot 3.1.x. It sounds like that's not the case for you but I cannot tell why from what you have described so far. If you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

j2yemi commented 1 year ago

InitializrSpringbootProject.zip Thank you for the reply. I have reproduced the issue here and attached the zip. hibernate 6.2.2

wilkinsona commented 1 year ago

Thanks for the sample. Unfortunately, it doesn't reproduce the problem. What I start the app, it updates the schema to create the table for the application's one entity:

2023-06-20T08:27:48.308+01:00 DEBUG 62931 --- [  restartedMain] org.hibernate.SQL                        : 
    create table paxi.roles (
        id serial not null,
        name varchar(20),
        primary key (id)
    )
Hibernate: 
    create table paxi.roles (
        id serial not null,
        name varchar(20),
        primary key (id)
    )

To investigate further we will need a sample that reproduces the problem.

j2yemi commented 1 year ago

Thank you for your response. Yes it ouputs that but the tables are not created in the postgresql db.

If you check you won't find them. Strange also it didn't throw error... i think this is a bug

Screenshot 2023-06-20 at 12 17 06 PM
wilkinsona commented 1 year ago

As shown by psql, the table is created as expected in the paxi schema:

paxi=# set SEARCH_PATH to paxi;
SET
paxi=# \dt
          List of relations
 Schema | Name  | Type  |   Owner    
--------+-------+-------+------------
 paxi   | roles | table | foodfinder
(1 row)

Looking at your screenshot, there's no paxi schema in your database.

If I delete the paxi schema from my database and restart the app, Postgres logs the following:

2023-06-20 12:08:09.766 UTC [106] ERROR:  schema "paxi" does not exist at character 19
2023-06-20 12:08:09.766 UTC [106] STATEMENT:  
        create table paxi.roles (
            id serial not null,
            name varchar(20),
            primary key (id)
        )

This problem occurs silently as you have tuned Hibernate's logging to only show error-level logging:

logging.level.org.hibernate: ERROR

If I remove this and restart the app again, the following is logged:

2023-06-20T13:10:35.488+01:00  WARN 87590 --- [  restartedMain] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    create table paxi.roles (
        id serial not null,
        name varchar(20),
        primary key (id)
    )" via JDBC [ERROR: schema "paxi" does not exist
  Position: 19]

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    create table paxi.roles (
        id serial not null,
        name varchar(20),
        primary key (id)
    )" via JDBC [ERROR: schema "paxi" does not exist
  Position: 19]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:92) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:574) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:514) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.createTable(AbstractSchemaMigrator.java:315) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:80) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:232) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:117) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:284) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.lambda$process$5(SchemaManagementToolCoordinator.java:143) ~[hibernate-core-6.2.2.Final.jar:6.2.2.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.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.boot.internal.SessionFactoryObserverForSchemaExport.sessionFactoryCreated(SessionFactoryObserverForSchemaExport.java:37) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryCreated(SessionFactoryObserverChain.java:35) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:291) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:431) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1455) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:66) ~[spring-orm-6.0.9.jar:6.0.9]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.0.9.jar:6.0.9]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.0.9.jar:6.0.9]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.0.9.jar:6.0.9]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1816) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.9.jar:6.0.9]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1156) ~[spring-context-6.0.9.jar:6.0.9]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:931) ~[spring-context-6.0.9.jar:6.0.9]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.9.jar:6.0.9]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.0.jar:3.1.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:733) ~[spring-boot-3.1.0.jar:3.1.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435) ~[spring-boot-3.1.0.jar:3.1.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-3.1.0.jar:3.1.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1305) ~[spring-boot-3.1.0.jar:3.1.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1294) ~[spring-boot-3.1.0.jar:3.1.0]
    at com.example.demo.DemoApplication.main(DemoApplication.java:11) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-3.1.0.jar:3.1.0]
Caused by: org.postgresql.util.PSQLException: ERROR: schema "paxi" does not exist
  Position: 19
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2713) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2401) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:368) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:498) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:415) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:335) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:321) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:297) ~[postgresql-42.6.0.jar:42.6.0]
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:292) ~[postgresql-42.6.0.jar:42.6.0]
    at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:94) ~[HikariCP-5.0.1.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) ~[HikariCP-5.0.1.jar:na]
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:78) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
    ... 43 common frames omitted
wilkinsona commented 1 year ago

The schema wasn't created automatically as you've got a typo in the name of the property. It should be spring.jpa.properties.hibernate.hbm2ddl.create_namespaces=true but you have spring.jpa.properties.hibernate.hbm2dll.create_namespaces=true (hbm2ddl rather than hbm2dll).

j2yemi commented 1 year ago

@wilkinsona Thank you very much for pointing out the error. I changed it to hbm2ddl and it works, creating the schema paxi. Strange hbm2dll works for previous hibernate version.

Once again thanks for your time.

wilkinsona commented 1 year ago

There was a typo in the property name in Hibernate. They fixed it in a backwards compatible way by supporting both properties for a while. I suspect they removed that backwards compatibility in 6.0.

j2yemi commented 1 year ago

This quite sums it up. Spent 48hrs on this already. They removed it in 6.2.X i think.

URRG commented 1 year ago

@wilkinsona Hello I also need some help on this issue. Actually I have created a spring boot service and tried connecting it with mysql. The program runs no errors but Hibernate doesnt create a table in database.

URRG commented 1 year ago

eclipse_z3wwfaCKGN

URRG commented 1 year ago

MySQLWorkbench_INbDmMU9Gh

wilkinsona commented 1 year ago

@UURG If you need some help with Hibernate, please ask the Hibernate community.

cakimaki commented 9 months ago

@URRG have you found solution?