Как использовать второй источник данных весной?

Я скачал пример кода здесь

https://github.com/spring-projects/spring-data-examples/tree/master/jpa/multiple-datasources

но я до сих пор не понимаю, как репозиторий связан с источником данных. Даже когда я просматриваю класс конфигурации, он не ссылается на репозиторий. И внутри интерфейса репозитория он не ссылается на источник данных или конфигурацию.

Итак, когда вы используете два разных репозитория для сохранения, как он узнает, к какому источнику данных обращаться для каждого репо?


person erotsppa    schedule 23.10.2019    source источник
comment
Я думаю, из-за сканирования компонентов пакета, которое определено в каждом классе конфигурации.   -  person Christian Altamirano Ayala    schedule 23.10.2019


Ответы (2)


В репозитории с примерами, которые вы связали, каждый класс конфигурации помечен @EnableJpaRepositories, который выполняет сканирование репозиториев только в пакете аннотированного класса плюс подпакеты - здесь происходит связь между источником данных и репозиторием.

person Maciej Walkowiak    schedule 23.10.2019
comment
Итак, репозитории настроены на основе класса Config в том же пакете? Такой странный дизайн, почему? Что делать, если у меня есть репозитории, разбросанные по множеству разных пакетов? Мне нужно создать конфигурацию для каждого, даже если я хочу, чтобы все они использовали один и тот же? Если я не создаю конфигурацию, она как-то использует значение по умолчанию? - person erotsppa; 24.10.2019

Обратите внимание на конфигурации (прокомментированные как /* важные */)

в OrderConfig

@Configuration

/* important */
@EnableJpaRepositories(entityManagerFactoryRef = "orderEntityManagerFactory",
        transactionManagerRef = "orderTransactionManager")

class OrderConfig {

    @Bean
    PlatformTransactionManager orderTransactionManager() {
        return new JpaTransactionManager(orderEntityManagerFactory().getObject());
    }

    @Bean
    LocalContainerEntityManagerFactoryBean orderEntityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

        /* important */
        factoryBean.setDataSource(orderDataSource());
        factoryBean.setJpaVendorAdapter(vendorAdapter);
        factoryBean.setPackagesToScan(OrderConfig.class.getPackage().getName());

        return factoryBean;
    }

    @Bean
    DataSource orderDataSource() {

        return new EmbeddedDatabaseBuilder().//
                setType(EmbeddedDatabaseType.HSQL).//
                setName("orders").//
                build();
    }
}

и CustomerConfig

@Configuration

/* important */
@EnableJpaRepositories(entityManagerFactoryRef = "customerEntityManagerFactory",
        transactionManagerRef = "customerTransactionManager")

class CustomerConfig {

    @Bean
    PlatformTransactionManager customerTransactionManager() {
        return new JpaTransactionManager(customerEntityManagerFactory().getObject());
    }

    @Bean
    LocalContainerEntityManagerFactoryBean customerEntityManagerFactory() {

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

        /* important */
        factoryBean.setDataSource(customerDataSource());
        factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        factoryBean.setPackagesToScan(CustomerConfig.class.getPackage().getName());

        return factoryBean;
    }

    @Bean
    DataSource customerDataSource() {

        return new EmbeddedDatabaseBuilder().//
                setType(EmbeddedDatabaseType.HSQL).//
                setName("customers").//
                build();
    }
}

и, наконец, аннотация @Transactional в DataInitializer

/* important */
@Transactional("customerTransactionManager")

public CustomerId initializeCustomer() {
    return customers.save(new Customer("Dave", "Matthews")).getId();
}

использует customerTransactionManager, настроенный в CustomerConfig

а также,

/* important */
@Transactional("orderTransactionManager")

public Order initializeOrder(CustomerId customer) {

   Assert.notNull(customer, "Customer identifier must not be null!");

   Order order = new Order(customer);
   order.add(new LineItem("Lakewood Guitar"));

   return orders.save(order);
}

использует orderTransactionManager, настроенный в OrderConfig

По сути, вы настраиваете разные datasources, разные entityManagers, разные transactionManagers и ссылаетесь на них конкретно по своему выбору.

person Isank    schedule 23.10.2019
comment
Итак, репозитории настроены на основе класса Config в том же пакете? Такой странный дизайн, почему? Что делать, если у меня есть репозитории, разбросанные по множеству разных пакетов? Мне нужно создать конфигурацию для каждого, даже если я хочу, чтобы все они использовали один и тот же? Если я не создаю конфигурацию, она как-то использует значение по умолчанию? - person erotsppa; 24.10.2019