#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 для определения того, какой именно бин нужен.
Комментариев нет:
Отправить комментарий