spring-boot 应用程序不会将夹具加载到多个数据源之一

Posted

技术标签:

【中文标题】spring-boot 应用程序不会将夹具加载到多个数据源之一【英文标题】:spring-boot application doesn't load fixtures into one of multiple data sources 【发布时间】:2017-08-24 11:16:44 【问题描述】:

在我的 Spring Boot 应用程序 (1.5.2.RELEASE) 启动期间加载数据固定装置时遇到了一些问题。该应用程序使用两个不同的数据库连接,一个连接到我们的客户 postgresql 数据库,我们无权在该数据库上创建、插入或更新任何内容。另一个数据库是本地嵌入式 h2 数据库(文件)。我想在应用程序启动期间通过使用 here 描述的 spring boot 数据库初始化阶段将一些数据加载到该 h2 数据库中,但数据从未插入到 h2 数据库中,它保持为空,因为我可以看到使用 squirrel- sql.

这是我的application.properties中的配置:

spring.datasource.abc.driver-class-name=org.postgresql.Driver
spring.datasource.abc.initialize=false
spring.datasource.abc.url=jdbc:postgresql://localhost:5432/abc
spring.datasource.abc.username=abc
spring.datasource.abc.password=abc

spring.datasource.def.driver-class-name=org.h2.Driver
spring.datasource.def.initialize=true
spring.datasource.def.url=jdbc:h2:./$path.prefixdef/def;DB_CLOSE_ON_EXIT=FALSE'
spring.datasource.def.data=classpath:/data-h2.sql

我将 Spring Boot 配置为使用两个不同的数据库,如 *** post 中所述,如果我手动将数据预插入 h2 数据库,一切正常。

我的 postgresql 数据源的配置:

@Configuration
@EnableJpaRepositories(basePackages = "....abc", entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager")
public class AbcDatabaseConfig


    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.abc")
    public DataSource dataSource()
    
        return DataSourceBuilder.create().build();
    

    @Primary
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
    
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("....abc");
        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl-auto", "none");
        properties.put("hibernate.ejb.entitymanager_factory_name", "entityManagerFactory");
        em.setJpaPropertyMap(properties);

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        return em;
    

    @Primary
    @Bean(name = "transactionManager")
    public JpaTransactionManager transactionManager(@Qualifier("entityManagerFactory") final EntityManagerFactory factory)
    
        return new JpaTransactionManager(factory);
    


h2-datasource的配置:

@Configuration
@EnableJpaRepositories(basePackages = "....def", entityManagerFactoryRef = "defEntityManagerFactory", transactionManagerRef = "defTransactionManager")
public class InavetDatabaseConfig


    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.def")
    public DataSource defDataSource()
    
        return DataSourceBuilder.create().build();
    

    @Bean(name = "defEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean defEntityManagerFactory()
    
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(defDataSource());
        em.setPackagesToScan("....def");

        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", "create");
        properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        properties.put("hibernate.ejb.entitymanager_factory_name", "defEntityManagerFactory");
        em.setJpaPropertyMap(properties);

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        return em;
    

    @Bean(name = "defTransactionManager")
    public JpaTransactionManager defTransactionManager(
            @Qualifier("defEntityManagerFactory") final EntityManagerFactory factory)
    
        return new JpaTransactionManager(factory);
    


【问题讨论】:

【参考方案1】:

我发现,只有 @Primary 标记的数据源会加载固定装置。我对这种行为的解决方法是在我的应用程序中添加这样的代码:

    ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.setContinueOnError(true);
    populator.addScript(new PathResource("src/main/resources/data-h2.sql"));
    DataSource dataSource = (DataSource) cac.getBean("defDataSource");
    DatabasePopulatorUtils.execute(populator, dataSource);

其中 cac 是您获得的 ConfigurableApplicationContext 实例作为返回值:SpringApplication.run(,);

【讨论】:

以上是关于spring-boot 应用程序不会将夹具加载到多个数据源之一的主要内容,如果未能解决你的问题,请参考以下文章

如何从夹具远程加载数据

(Django)当我尝试将夹具文件加载到我的数据库中时,我不断收到字段冲突错误

加载夹具时 django unittest 出错

Doctrine(Symfony) 加载夹具,参考不存在

带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题

Django 夹具未加载 loaddata