Spring引导没有为我的一个存储库使用正确的数据源(我有两个)

问题描述 投票:0回答:2

我有主数据源的以下配置。

@Configuration
@PropertySource({ "classpath:application.properties" })
@EnableJpaRepositories(
        basePackages = "com.my.proj.datastores.authentication",
        entityManagerFactoryRef = "userEntityManager",
        transactionManagerRef = "userTransactionManager"
)
public class SpringDatabaseConfig {
    @Autowired
    private Environment env;

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean userEntityManager() {
        LocalContainerEntityManagerFactoryBean em
                = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(userDataSource());
        em.setPackagesToScan(
                new String[] { "com.my.proj.datastores.authentication" });

        HibernateJpaVendorAdapter vendorAdapter
                = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<>();
        properties.put("hibernate.hbm2ddl.auto",
                env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect",
                env.getProperty("hibernate.dialect"));
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Primary
    @Bean
    public DataSource userDataSource() {

        DriverManagerDataSource dataSource
                = new DriverManagerDataSource();
        dataSource.setDriverClassName(
                env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource.jdbc-url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.datasource.password"));

        return dataSource;
    }

    @Primary
    @Bean
    public PlatformTransactionManager userTransactionManager() {

        JpaTransactionManager transactionManager
                = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                userEntityManager().getObject());
        return transactionManager;
    }
}

我的第二个数据源也有这个配置:

@Configuration
@PropertySource({ "classpath:application.properties" })
@EnableJpaRepositories(
        basePackages = "com.my.proj.datastores.ngl",
        entityManagerFactoryRef = "otherTypeEntityManager",
        transactionManagerRef = "otherTypeTransactionManager"
)
public class OracleDatabaseConfig {
    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean otherTypeEntityManager() {
        LocalContainerEntityManagerFactoryBean em
                = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(otherTypeDataSource());
        em.setPackagesToScan(
                new String[] { "com.my.proj.datastores.ngl" });

        HibernateJpaVendorAdapter vendorAdapter
                = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<>();
        properties.put("hibernate.hbm2ddl.auto",
                env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect",
                env.getProperty("hibernate.dialect"));
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Bean
    public DataSource otherTypeDataSource() {

        DriverManagerDataSource dataSource
                = new DriverManagerDataSource();
        dataSource.setDriverClassName(
                env.getProperty("spring.second.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.second.datasource.jdbc-url"));
        dataSource.setUsername(env.getProperty("spring.second.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.second.datasource.password"));

        return dataSource;
    }

    @Bean
    public PlatformTransactionManager otherTypeTransactionManager() {

        JpaTransactionManager transactionManager
                = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                otherTypeEntityManager().getObject());
        return transactionManager;
    }
}

主要的是处理auth的数据库,第二个是我想从中获取数据的地方。在理想的世界中,这些将是一个数据库,但这是该项目的方式。

我也有这个application.properties:

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.jdbc-url= ${DATASOURCE_URL}
spring.datasource.username= ${DATASOURCE_USERNAME}
spring.datasource.password= ${DATASOURCE_PASSWORD}
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.second.datasource.jdbc-url=jdbc:oracle:thin:@localhost:1521:XE
spring.second.datasource.username=admin
spring.second.datasource.password=password
spring.second.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

应用程序运行,@Primary数据源似乎工作。

但是,我不确定如何“连接”第二个,以便存储库类使用它在主要的一个上。

我确实有不同包中的存储库,因为我读到了我需要的。

我试图在我的存储库中运行的查询是一个简单的“select all”在表上,我得到一个错误,表示该表不存在...但我知道它正在尝试使用@Primary,因为错误是MySql异常,第二个数据源是Oracle数据源。

有任何想法吗?

java spring-boot ojdbc
2个回答
0
投票

你需要的是创建2个configuration类,分开model/repository packages等,使配置容易这样。

 com.packagename.multidatasources
                  ├── first
                  │   ├── model
                  │   └── repository
                  └── second
                      ├── model
                      └── repository

然后为datasources定义配置并指定@EnableJpaRepositories注释以使用数据源并扫描相应存储库所在的基础包。

使用以下链接来了解如何执行此操作,您可能会发现entityManager和transactionManager有一点额外但最佳实践包括它们:

请参阅spring doc以获取相同的here


-1
投票

这种情况很复杂,但您可以通过创建另一个包含application-dev.properties和application-staging.properties的application.properties来使其变得非常简单。使用新实现,将每个数据源放在其中一个创建的环境中。

例如,application-dev.properties可以包含以下配置:

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
   spring.datasource.jdbc-url= ${DATASOURCE_URL}
   spring.datasource.username= ${DATASOURCE_USERNAME}
   spring.datasource.password= ${DATASOURCE_PASSWORD}
   spring.datasource.driver-class-name=com.mysql.jdbc.Driver

和application-staging.properties可以包含:

spring.second.datasource.jdbc-url=jdbc:oracle:thin:@localhost:1521:XE
spring.second.datasource.username=admin
spring.second.datasource.password=password
spring.second.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

完成后,您可以将spring.active.profile = dev添加到application-dev.properties文件的顶部,将spring.active.profile = staging添加到application-staging.properties文件的顶部。

最后,您可以将系统启动application.properties文件中要使用的环境设置为spring.active.profile = dev或staging(视情况而定)。这种方法应该能够毫不费力地解决问题。

总之,您将共有3个.properties文件,如下所示:1。application.properties 2. application-dev.properties 3. application-staging.properties

但是,您需要注释掉您的数据配置类。

我希望这有帮助。快乐的编码。

© www.soinside.com 2019 - 2024. All rights reserved.