简体   繁体   中英

Spring Boot / Data doesn't recreate tables

I'm trying to configure Spring Boot / Data to recreate tables when app initialize. To this I configured ddl-auto to create. I'm using two data sources.

When tables do not exist, they are created. But when tables exist, they are not recreated. I thought ddl-auto create ("creates the schema, destroying previous data.") would always recreate the tables.

application.yaml

spring:
   profiles: spring
   jpa:
      generate-ddl: true
      hibernate: 
         ddl-auto: create
      show-sql: true
      properties:
         hibernate:
            dialect: org.hibernate.dialect.MySQL5InnoDBDialect
            format_sql: true

dba:
   datasource:
      url: jdbc:mysql://localhost:3306/DBA
      username: root
      password: 123
      driver-class-name: com.mysql.cj.jdbc.Driver

dbb:
   datasource:
      url: jdbc:mysql://localhost:3306/DBB
      username: root
      password: 123
      driver-class-name: com.mysql.cj.jdbc.Driver

My configuration files:

@SpringBootApplication
@ComponentScan( basePackages = {"com.example.mds"} )
public class EMdsApplication {

    public static void main(String[] args) {
        SpringApplication.run(EMdsApplication.class, args);
    }

}

DBAConfig.java

@Configuration
@EntityScan(basePackages = {"com.example.mds.model"} )
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "dba_emf",
        transactionManagerRef = "dba_tm",
        basePackages = {"com.example.mds.repository"}
)
public class DBAConfig {


    @Primary
    @Bean(name = "dba_ds")
    @ConfigurationProperties(prefix = "dba.datasource")
    public DataSource dataSource(@Qualifier("dba_dsp") DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Primary
    @Bean(name = "dba_emf")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("dba_ds") DataSource datasource) {
        return builder
                  .dataSource(datasource)
                  .packages("com.example.mds.model")
                  .persistenceUnit("dba_pu")
                  .build();
    }

    @Primary
    @Bean(name = "dba_tm")
    public PlatformTransactionManager transactionManager(@Qualifier("dba_emf") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Primary
    @Bean(name = "dba_dsp")
    @ConfigurationProperties(prefix = "dba.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }   

}

DBBConfig.java

@Configuration
@EntityScan(basePackages = {"com.example.mds.dbb.model"} )
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "dbb_emf",
        transactionManagerRef = "dbb_tm",
        basePackages = {"com.example.mds.dbb.repository"}
)
public class DBBConfig {

    @Bean(name = "dbb_ds")
    @ConfigurationProperties(prefix = "dbb.datasource")
    public DataSource dataSource(@Qualifier("dbb_dsp") DataSourceProperties properties) {
        return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }

    @Bean(name = "dbb_emf")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("dbb_ds") DataSource datasource) {
        return builder
                  .dataSource(datasource)
                  .packages("com.example.mds.dbb.model")
                  .persistenceUnit("dbb_pu")
                  .build();
    }

    @Bean(name = "dbb_tm")
    public PlatformTransactionManager transactionManager(@Qualifier("dbb_emf") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

    @Bean(name = "dbb_dsp")
    @ConfigurationProperties(prefix = "dbb.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }   

}

You would need to use create-drop property in case you want to drop and create tables. This should be used for testing purposes only and not for production use. Refer to this question for details

In application.yaml change ddl-auto: create to ddl-auto: create-drop .
It will drop the schema when session factory is closed at application shut down and will create new schema at application startup.

In application.yaml change ddl-auto: create to ddl-auto: update .

From the question what i understand is that you just want to update the schme when it is already present.But with your current configuration it is only getting created if the tables are not present.You want to update the tables if they are already present.

Please take care to ensure that you use this property only for test scenarios or for development purposes .Ensure that you set the ddl-auto as none for production environment.

Try setting the application.yml as below:

spring:
   profiles: spring
   jpa:
      generate-ddl: true
      hibernate: 
         ddl-auto: update

The possible values for ddl-auto are:

validate: validate the schema, makes no changes to the database.
update: update the schema.
create: creates the schema, destroying previous data.
create-drop: drop the schema at the end of the session.

The update operation will query the JDBC driver's API to get the database metadata and then Hibernate compares the object model it creates based on reading your annotated classes or HBM XML mappings and will attempt to adjust the schema on-the-fly.

Related post: How does spring.jpa.hibernate.ddl-auto property exactly work in Spring?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM