title: Spring Boot with multiple data sources using same repositories and model classes?
body: <p>I have to do a Spring Boot version 1.5 application that can do like this: it creates an object and try to persist to both data sources (example: 2 databases named: test_book_1 and test_book_2 in Postgresql).</p>
  
  <p>I have found an example that could work for 2 different objects (Author: A, Book: B) which can be stored in different databases (A goes to test_book_1 and B goes to test_book_2). This is a good example but it is not what I wanted.
  <a href="http://www.yonatanwilkof.net/multiple-flyway-initialized-data-sources-in-spring-boot/" rel="noreferrer">Store separate objects to different data sources</a></p>
  
  <p>I got the idea that I need to define 2 custom JPA DatabaseConfigurations and need to config them to manage the same repository and domain class. However, Spring only use the second class as Qualifier to inject for JPA repository (I understand that when both configurations point to same class then the second one can override). </p>
  
  <p><strong>The question is, how can I tell Spring to let it knows that when it should inject the correct Bean (BookRepository)</strong> from the wanted data source (I wanted to persist the object to both data sources, not just the second one).</p>
  
  <p>Here is the modified code from the example link above.</p>
  
  <p>An application.properties file which is modified to create 2 database in Postgresql instead of 1 in Postgresql and 1 in Mysql.</p>
  
  <pre><code>server.port=8082
  # -----------------------
  # POSTGRESQL DATABASE CONFIGURATION
  # -----------------------
      spring.postgresql.datasource.url=jdbc:postgresql://localhost:5432/test_book_db
  spring.postgresql.datasource.username=petauser
  spring.postgresql.datasource.password=petapasswd
  spring.postgresql.datasource.driver-class-name=org.postgresql.Driver
  
  # ------------------------------
  # POSTGRESQL 1 DATABASE CONFIGURATION
  # ------------------------------
  
     spring.mysql.datasource.url=jdbc:postgresql://localhost:5432/test_author_db
  spring.mysql.datasource.username=petauser
  spring.mysql.datasource.password=petapasswd
  spring.mysql.datasource.driver-class-name=org.postgresql.Driver
  </code></pre>
  
  <p>package: com.roufid.tutorial.configuration
  class APostgresqlConfiguration</p>
  
  <pre><code>package com.roufid.tutorial.configuration;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Properties;
  import java.util.stream.Collectors;
  
  import javax.persistence.EntityManagerFactory;
  import javax.sql.DataSource;
  
  import org.springframework.beans.factory.annotation.Qualifier;
  import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.Primary;
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.core.io.Resource;
  import org.springframework.core.io.support.PropertiesLoaderUtils;
  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  import org.springframework.orm.jpa.JpaTransactionManager;
  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  import org.springframework.transaction.PlatformTransactionManager;
  import org.springframework.transaction.annotation.EnableTransactionManagement;
  
  import com.roufid.tutorial.entity.postgresql.Book;
  
  /**
   * Spring configuration of the "PostgreSQL" database.
   *
   * @author Radouane ROUFID.
   *
   */
  @Configuration
  @EnableTransactionManagement
  @EnableJpaRepositories(
          entityManagerFactoryRef = "postgresqlEntityManager",
          transactionManagerRef = "postgresqlTransactionManager",
          basePackages = "com.roufid.tutorial.dao.postgresql"
  )
  public class APostgresqlConfiguration {
  
      /**
       * PostgreSQL datasource definition.
       *
       * @return datasource.
       */
      @Bean
      @Primary
      @ConfigurationProperties(prefix = "spring.postgresql.datasource")
      public DataSource postgresqlDataSource() {
          return DataSourceBuilder
                  .create()
                  .build();
      }
  
      /**
       * Entity manager definition.
       *
       * @param builder an EntityManagerFactoryBuilder.
       * @return LocalContainerEntityManagerFactoryBean.
       */
      @Primary
      @Bean(name = "postgresqlEntityManager")
      public LocalContainerEntityManagerFactoryBean postgresqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
          return builder
                  .dataSource(postgresqlDataSource())
                  .properties(hibernateProperties())
                  .packages(Book.class)
                  .persistenceUnit("postgresqlPU")
                  .build();
      }
  
      @Primary
      @Bean(name = "postgresqlTransactionManager")
      public PlatformTransactionManager postgresqlTransactionManager(@Qualifier("postgresqlEntityManager") EntityManagerFactory entityManagerFactory) {
          return new JpaTransactionManager(entityManagerFactory);
      }
  
      private Map&lt;String, Object&gt; hibernateProperties() {
  
          Resource resource = new ClassPathResource("hibernate.properties");
  
          try {
              Properties properties = PropertiesLoaderUtils.loadProperties(resource);
              return properties.entrySet().stream()
                      .collect(Collectors.toMap(
                              e -&gt; e.getKey().toString(),
                              e -&gt; e.getValue())
                      );
          } catch (IOException e) {
              return new HashMap&lt;String, Object&gt;();
          }
      }
  }
  </code></pre>
  
  <p>package: com.roufid.tutorial.configuration
  class MysqlConfiguration</p>
  
  <pre><code>package com.roufid.tutorial.configuration;
  
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Properties;
  import java.util.stream.Collectors;
  
  import javax.persistence.EntityManagerFactory;
  import javax.sql.DataSource;
  
  import org.springframework.beans.factory.annotation.Qualifier;
  import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
  import org.springframework.boot.context.properties.ConfigurationProperties;
  import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.core.io.ClassPathResource;
  import org.springframework.core.io.Resource;
  import org.springframework.core.io.support.PropertiesLoaderUtils;
  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
  import org.springframework.orm.jpa.JpaTransactionManager;
  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
  import org.springframework.transaction.PlatformTransactionManager;
  import org.springframework.transaction.annotation.EnableTransactionManagement;
  
  import com.roufid.tutorial.entity.mysql.Author;
  import com.roufid.tutorial.entity.postgresql.Book;
  
  /**
   * Spring configuration of the "mysql" database.
   *
   * @author Radouane ROUFID.
   *
   */
  @Configuration
  @EnableTransactionManagement
  @EnableJpaRepositories(
          entityManagerFactoryRef = "mysqlEntityManager",
          transactionManagerRef = "mysqlTransactionManager",
          basePackages = "com.roufid.tutorial.dao.postgresql"
  )
  public class MysqlConfiguration {
  
      /**
       * MySQL datasource definition.
       *
       * @return datasource.
       */
      @Bean
      @ConfigurationProperties(prefix = "spring.mysql.datasource")
      public DataSource mysqlDataSource() {
          return DataSourceBuilder
                  .create()
                  .build();
      }
  
      /**
       * Entity manager definition.
       *
       * @param builder an EntityManagerFactoryBuilder.
       * @return LocalContainerEntityManagerFactoryBean.
       */
      @Bean(name = "mysqlEntityManager")
      public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(EntityManagerFactoryBuilder builder) {
          return builder
                  .dataSource(mysqlDataSource())
                  .properties(hibernateProperties())
                  .packages(Book.class)
                  .persistenceUnit("mysqlPU")
                  .build();
      }
  
      /**
       * @param entityManagerFactory
       * @return
       */
      @Bean(name = "mysqlTransactionManager")
      public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysqlEntityManager") EntityManagerFactory entityManagerFactory) {
          return new JpaTransactionManager(entityManagerFactory);
      }
  
      private Map&lt;String, Object&gt; hibernateProperties() {
  
          Resource resource = new ClassPathResource("hibernate.properties");
      }
  }    try {
              Properties properties = PropertiesLoaderUtils.loadProperties(resource);
              return properties.entrySet().stream()
                      .collect(Collectors.toMap(
                              e -&gt; e.getKey().toString(),
                              e -&gt; e.getValue())
                      );
          } catch (IOException e) {
              return new HashMap&lt;String, Object&gt;();
          }
      }
  }
  </code></pre>
  
  <p>package com.roufid.tutorial.dao.postgresql
  class BookRepository</p>
  
  <pre><code>package com.roufid.tutorial.dao.postgresql;
  
  import org.springframework.data.repository.CrudRepository;
  
  import com.roufid.tutorial.entity.postgresql.Book;
  
  /**
   * Book repository.
   * 
   * @author Radouane ROUFID.
   *
   */
  public interface BookRepository extends CrudRepository&lt;Book, Long&gt; {
  
  }
  </code></pre>
  
  <p>package com.roufid.tutorial.entity.postgresql
  class Book</p>
  
  <pre><code>package com.roufid.tutorial.entity.postgresql;
  
  import java.io.Serializable;
  
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.Id;
  import javax.persistence.Table;
  
  @Entity
  @Table(name = "BOOK")
  public class Book implements Serializable {
  
      private static final long serialVersionUID = -9019470250770543773L;
  
      @Id
      private Long id;
  
      @Column
      private String name;
  
      @Column
      private Long authorId;
  
      ...
      // Setters, Getters
  
  }
  </code></pre>
  
  <p>And a test class to inject the BookRepository which will use the MysqlConfiguration class (second datasource) only.</p>
  
  <pre><code>@RunWith(SpringRunner.class)
  @SpringBootTest
  public class ApplicationTest {
  @Autowired
  private BookRepository bookRepository;
  @Before
  public void init() {   
      Book book = new Book();
      book.setId(bookId);
      book.setName("Spring Boot Book");
  
      // How can it persist to the first datasource?  
      bookRepository.save(book);
  }
  </code></pre>
  
  <p>}</p>