복붙노트

[SPRING] 스프링 부트 2 다중 데이터 소스가 스키마 초기화

SPRING

스프링 부트 2 다중 데이터 소스가 스키마 초기화

Spring Boot 2 애플리케이션은 오라클 하나와 H2 두 개의 데이터 소스를 사용합니다. H2 데이터 소스는 보조로 설정되어 있으며 시작할 때 스키마를 만들고 싶지만 schema.sql 파일은 절대 실행하지 않습니다. 이것은 내 데이터 소스 구성 파일입니다.

@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties primaryDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSource primaryDataSource() {
        return primaryDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean
    @ConfigurationProperties("spring.runlogdatasource")
    public DataSourceProperties runlogDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.runlogdatasource")
    public DataSource runlogDataSource() {
        return runlogDataSourceProperties().initializeDataSourceBuilder().build();
    }
}

이것은 내 application.properties 파일입니다.

spring.datasource.url=jdbc:oracle:thin:@my.database.com:1521/mydb
spring.datasource.username=test
spring.datasource.password=ENC(3PXcnoBndLpWN1EcMtmIn+odOwhdWjSrqANijutxuekKEIOco64Jew==)
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.initialization-mode=never
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=10
jasypt.encryptor.bean=stringEncryptor
spring.runlogdatasource.url=jdbc:h2:~/runlogdb;CIPHER=AES;DB_CLOSE_ON_EXIT=FALSE;
spring.runlogdatasource.username=sa
spring.runlogdatasource.password=ENC(3PXcnoBndLpWN1EcMtmIn+odOwhdWjSrqANijutxuekKEIOco64Jew==)
spring.runlogdatasource.driverClassName=org.h2.Driver
spring.runlogdatasource.platform=h2
spring.runlogdatasource.schema=classpath:schema-h2.sql

기본 데이터 소스의 경우, 데이터 소스가 스키마를로드하려고 시도하는 DataSourceInitializerInvoker에 들어가는 것을 볼 수 있지만 schema-all.sql 파일이 없으므로 건너 뜁니다. 그러나 스키마 -h2.sql 파일이 있지만 보조 데이터 원본의 경우 DataSourceInitializerInvoker를 입력하지 않으므로 스키마를 초기화하지 않습니다. 어떤 도움이라도 대단히 감사하겠습니다!

해결법

  1. ==============================

    1.이는 예상되는 동작입니다. 기본 데이터 소스가 지정되면이 데이터 소스의 스키마와 데이터 만 실행됩니다. 이 동작을 수행하기 위해 수행해야하는 작업은 두 데이터 소스 각각에 대해 DataSourceInitializer를 정의하는 것입니다.

    이는 예상되는 동작입니다. 기본 데이터 소스가 지정되면이 데이터 소스의 스키마와 데이터 만 실행됩니다. 이 동작을 수행하기 위해 수행해야하는 작업은 두 데이터 소스 각각에 대해 DataSourceInitializer를 정의하는 것입니다.

            @Bean
            public DataSourceInitializer dataSourceInitializer1(@Qualifier("datasource1") DataSource datasource) {
                ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
                resourceDatabasePopulator.addScript(new ClassPathResource("schema-h22.sql"));
                resourceDatabasePopulator.addScript(new ClassPathResource("data-h22.sql"));
    
                    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
                    dataSourceInitializer.setDataSource(datasource);
                    dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
                    return dataSourceInitializer;
            }
    
        @Bean
        public DataSourceInitializer dataSourceInitializer2(@Qualifier("datasource2") DataSource datasource) {
            ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
            resourceDatabasePopulator.addScript(new ClassPathResource("schema-h21.sql"));
            resourceDatabasePopulator.addScript(new ClassPathResource("data-h21.sql"));
    
                DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
                dataSourceInitializer.setDataSource(datasource);
                dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
                return dataSourceInitializer;
        }
    

    또한 기본 스프링 데이터 초기화를 비활성화해야합니다. spring.datasource.initialization-mode = never를 통해이 작업을 수행 할 수 있습니다.

  2. ==============================

    2.데이터 소스에 해당하는 여러 Liquibase 구성을 사용할 수 있습니다. 두 데이터 소스의 스키마를 초기화하는 데 도움이 될 수 있습니다.

    데이터 소스에 해당하는 여러 Liquibase 구성을 사용할 수 있습니다. 두 데이터 소스의 스키마를 초기화하는 데 도움이 될 수 있습니다.

    샘플 : -

    ...
    
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.liquibase")
    public LiquibaseProperties primaryLiquibaseProperties() {
        return new LiquibaseProperties();
    }
    
    @Bean
    public SpringLiquibase primaryLiquibase() {
        return springLiquibase(primaryDataSource(), primaryLiquibaseProperties());
    }
    @Bean
    @ConfigurationProperties(prefix = "spring.runlogdatasource.liquibase")
    public LiquibaseProperties secondaryLiquibaseProperties() {
        return new LiquibaseProperties();
    }
    
    @Bean
    public SpringLiquibase secondaryLiquibase() {
        return springLiquibase(secondaryDataSource(), secondaryLiquibaseProperties());
    }
    
    private static SpringLiquibase springLiquibase(DataSource dataSource, LiquibaseProperties properties) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog(properties.getChangeLog());
        liquibase.setContexts(properties.getContexts());
        liquibase.setDefaultSchema(properties.getDefaultSchema());
        liquibase.setDropFirst(properties.isDropFirst());
        liquibase.setShouldRun(properties.isEnabled());
        liquibase.setLabels(properties.getLabels());
        liquibase.setChangeLogParameters(properties.getParameters());
        liquibase.setRollbackFile(properties.getRollbackFile());
        return liquibase;
    }
    ...
    

    U는 다음과 같이 속성을 편집 할 수 있습니다.

  3. from https://stackoverflow.com/questions/51146269/spring-boot-2-multiple-datasources-initialize-schema by cc-by-sa and MIT license