Skip to content

Instantly share code, notes, and snippets.

@alexaugustobr
Last active April 5, 2022 03:03
Show Gist options
  • Save alexaugustobr/e83bb589a7b4d00b34517d4d8dbc43bd to your computer and use it in GitHub Desktop.
Save alexaugustobr/e83bb589a7b4d00b34517d4d8dbc43bd to your computer and use it in GitHub Desktop.

Configurando dois dataSources com Spring Boot e Spring Data JPA

Primeiro é necessário preencher as configurações dos DataSources no arquivo de configuração. No nosso caso utilizamos no formato YML (application.yml), para criar dois DataSources, um para o banco de dados chamado "usuarios" e outro para "mensagens":

spring:
  datasource.mensagens:
    username: root
    url: jdbc:mysql://localhost:3306/awmensagens?createDatabaseIfNotExist=true&serverTimezone=UTC
    password:
  datasource.usuarios:
    username: root
    url: jdbc:mysql://localhost:3306/awusuarios?createDatabaseIfNotExist=true&serverTimezone=UTC
    password:

Em seguida, é precisa ler essas configurações para de fato criar os DataSources:

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.usuarios")
    public DataSourceProperties usuariosDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.mensagens")
    public DataSourceProperties mensagensDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    public DataSource usuariosDataSource() {
        return usuariosDataSourceProperties()
                .initializeDataSourceBuilder()
                .build();
    }

    @Bean
    public DataSource mensagensDataSource() {
        return mensagensDataSourceProperties()
                .initializeDataSourceBuilder()
                .build();
    }

}

Importante ao menos um deles precisa ser @Primary, para que o Spring funcione corretamente. Em seguida, para cada um dos seus DataSources, é necessário configurar um EntityManager, assim poderemos gerenciar as Entities e Repositories em cada um dos bancos de dados.

Este seria o exemplo para DataSource "usuarios":

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
		basePackages = "com.algaworks.example.usuario", 
		entityManagerFactoryRef = "usuariosEntityManagerFactory",
		transactionManagerRef = "usuariosTransactionManager"
)
public class UsuarioJpaConfiguration {

	@Bean
	@Primary
	public LocalContainerEntityManagerFactoryBean usuariosEntityManagerFactory(
			@Qualifier("usuariosDataSource") DataSource usuariosDataSource, 
			EntityManagerFactoryBuilder builder) {
		Map<String, Object> properties = new HashMap<String, Object>();
		properties.put("hibernate.hbm2ddl.auto", "update");
		
		return builder.dataSource(usuariosDataSource)
				.packages("com.algaworks.example.usuario")
				.properties(properties)
				.build();
	}

	@Bean
	public PlatformTransactionManager usuariosTransactionManager(
			@Qualifier("usuariosEntityManagerFactory") LocalContainerEntityManagerFactoryBean usuariosEMF) {
		return new JpaTransactionManager(Objects.requireNonNull(usuariosEMF.getObject()));
	}
	
}

DataSource "mensagens":

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
      basePackages = "com.algaworks.example.mensagem",
      entityManagerFactoryRef = "mensagensEntityManagerFactory",
      transactionManagerRef = "mensagensTransactionManager"
)
public class MensagemJpaConfiguration {

   @Bean
   public LocalContainerEntityManagerFactoryBean mensagensEntityManagerFactory(
         @Qualifier("mensagensDataSource") DataSource mensagensDataSource, 
         EntityManagerFactoryBuilder builder) {
      Map<String, Object> properties = new HashMap<String, Object>();
      properties.put("hibernate.hbm2ddl.auto", "update");
      return builder.dataSource(mensagensDataSource)
            .properties(properties)
            .packages("com.algaworks.example.mensagem")
            .build();
   }

   @Bean
   public PlatformTransactionManager mensagensTransactionManager(
         @Qualifier("mensagensEntityManagerFactory") LocalContainerEntityManagerFactoryBean mensagensEMF) {
      return new JpaTransactionManager(Objects.requireNonNull(mensagensEMF.getObject()));
   }
   
}

Nota que também é necessário ao menos um EntityManager como @Primary. Essa configuração será válida apenas para o pacote e subpacotes de "com.algaworks.example.usuario", assim qualquer Entity ou Repository destes pacotes, utilizaram esse EntityManager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment