membersound
membersound

Reputation: 86757

How to inject CrudRepository and EntityManager from secondary DataSource?

I want to initialize two DataSource in my app, as follows:

@Configuration
public class DataSourceConfig {
    @Bean
    @Primary
    @ConfigurationProperties(prefix="spring.datasource")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix="spring.datasource2")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

Now I want to use the secondary datasource explicit as follows:

public class SecondaryDbService {
   @Autowired
   private EntityManager em;

   @Autowired
   private SecondaryCrudRepository dao;
}

interface SecondaryCrudRepository implements CrudRepository<SecondaryEntity, Long> {
}

If configured as above, the service would use the primary datasource.

Question: how can I tell the CrudRepository to rely on the "secondaryDataSource"? And likewise, how can I inject the EntityManager from the "secondaryDataSource"?

Upvotes: 2

Views: 1100

Answers (1)

AndrewP
AndrewP

Reputation: 368

If you want to use multiple datasources, the key is to have the configurations for each Datasource in different packages. You will need to separate your entities between these packages according to which datasource they should access.

You will also have to implement both entity and transaction managers for each datasource in these packages.

To much theory ? in practical it would look something like this:

com.package1
- com.package1.entities
   - EntityClass1.java (annotated with @Entity)
- ConfigForDataSource1.java

com.package2
- com.package2.entities
   - EntityClass2.java (annotated with @Entity)
- ConfigForDataSource2.java

Here's how ConfigForDataSource1 would look like:

@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerDataSource1",
    basePackages = "com.package1",
    transactionManagerRef = "TransactionManagerDataSource1")
public class MasterDBConfig {

   @Bean(name="DataSource1")
   @ConfigurationProperties(prefix = "datasource1.datasource")
   public DataSource dataSource() {
       return DataSourceBuilder.create().build();
   }

   @Bean(name="entityManagerDataSource1")
   public LocalContainerEntityManagerFactoryBean entityManagerDataSource1(EntityManagerFactoryBuilder builder,@Qualifier("DataSource1") DataSource dataSource) {
       return builder.dataSource(dataSource).packages("com.package1").persistenceUnit("DataSource1").build();
    }

   @Bean(name = "TransactionManagerDataSource1")
   public PlatformTransactionManager TransactionManagerDataSource1(@Qualifier("entityManagerDataSource1") EntityManagerFactory entityManagerFactory) {
       return new JpaTransactionManager(entityManagerFactory);
   }
}

Then do the same for package 2 and enjoy.

Good luck !

Upvotes: 1

Related Questions