Страницы

Поиск по вопросам

суббота, 14 декабря 2019 г.

spring boot, multiple datasource

#java #spring #spring_boot


Есть приложение на spring boot, которое использует подключение к двум бд:
application.properties 

spring.datasource.url=jdbc:h2:mem
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver

another.datasource.url=jdbc:mysql://localhost:3306/test
another.datasource.username=root
another.datasource.password=
another.datasource.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
another.datasource.driverClassName=com.mysql.jdbc.Driver


RepositoryConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "anotherEntityManagerFactory",
        transactionManagerRef = "anotherTransactionManager",
        basePackages = {"test.repository.mysql"})
public class RepositoryConfig {

    @Autowired
    JpaVendorAdapter jpaVendorAdapter;

    @Value("${another.datasource.url}")
    private String databaseUrl;

    @Value("${another.datasource.username}")
    private String username;

    @Value("${another.datasource.password}")
    private String password;

    @Value("${another.datasource.driverClassName}")
    private String driverClassName;

    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl,
username, password);
        dataSource.setDriverClassName(driverClassName);
        return dataSource;
    }

    @Bean(name = "anotherEntityManager")
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Bean(name = "anotherEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        Properties properties = new Properties();
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(dataSource());
        emf.setJpaVendorAdapter(jpaVendorAdapter);
        emf.setPackagesToScan("test.entity.mysql");   // <- package for entities
        emf.setPersistenceUnitName("anotherEntity");
        emf.setJpaProperties(properties);
        emf.afterPropertiesSet();
        return emf.getObject();
    }

    @Bean(name = "anotherTransactionManager")
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory());
    }
}


При такой конфигурации работает подключение к двум бд, но в дефолтном datasource
используются все entity, как сделать, чтобы первый datasource, который в application.properties
как spring.datasource, использовал только свои entity?
    


Ответы

Ответ 1



Элегантное решение предложено в документации к spring-boot Суть в создании собственных ConfigurationProperty и использования атрибута prefix для спецификации. Далее можно разнести их по разным конфигурациям и воспользоваться аннотацией EntityScan Ну и конечно же можно сделать то, что вы пытались сделать, только более аккуратно @Bean public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(customerDataSource()) .packages(Customer.class) .persistenceUnit("customers") .build(); } @Bean public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(orderDataSource()) .packages(Order.class) .persistenceUnit("orders") .build(); } Для изоляции Entity я использую разные репозитории, пример из документации: @Configuration @EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "customerEntityManagerFactory") public class CustomerConfiguration { ... } @Configuration @EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "orderEntityManagerFactory") public class OrderConfiguration { ... } PS: Если не запуститься с ошибкой об уникальности бинов, то нужно один из бинов пометить как @Primary :)

Ответ 2



Нужно создать 2 бина DataSource. Добавить аннотацию @Qualifier. Дать им разные имена. ссылка на английском @Bean(name = "mysql") @Primary @ConfigurationProperties(prefix="datasource.mysql") public DataSourceProperties fooDataSourceProperties() { return DataSourceBuilder .create() .build(); } @Bean(name = "postgres") public DataSource fooDataSource() { return fooDataSourceProperties().initializeDataSourceBuilder().build(); } Далее используем @Qualifier для определения того, какой именно бин нужен.

Комментариев нет:

Отправить комментарий