1

Is it possible to save single entity to multiple Databse (DB1 and DB2) by spring boot.For example am having two MYSQL DB with same table while posting data i need to save the person details into two dbs at same .?or any other way doing spring .Already i created two db Connections if the entity are different means, I can save the data, but the entity are same means i cant able to do?

public class Person {
private Long id;
private String name;
private String city;
}

My tablesCREATE TABLEperson( idBIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, nameVARCHAR(255) DEFAULT NULL, cityVARCHAR(255) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=latin1

For two DBS Named as DB1 and DB2 MY Connection Config is

@Configuration
 @EnableJpaRepositories(basePackages = 
 {"com.onlinetutorialspoint.repository.db1"},
    entityManagerFactoryRef = "db1EntityManager",
    transactionManagerRef = "db1TransactionManager")
  public class DB1_DataSource {
@Autowired
private Environment env;
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean db1EntityManager() {
    LocalContainerEntityManagerFactoryBean em = new 
    LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db1Datasource());
    em.setPackagesToScan(new String[]
   {"com.onlinetutorialspoint.model.db1"});
    em.setPersistenceUnitName("db1EntityManager");
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<String, Object> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}
@Primary
@Bean
public DataSource db1Datasource() {
    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db1.datasource.url"));
    dataSource.setUsername(env.getProperty("db1.datasource.username"));
    dataSource.setPassword(env.getProperty("db1.datasource.password"));
    return dataSource;
}
@Primary
@Bean
public PlatformTransactionManager db1TransactionManager() {
    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db1EntityManager().getObject());
    return transactionManager;
}
}

For second DB

@Configuration
@EnableJpaRepositories(basePackages = 
{"com.onlinetutorialspoint.repository.db2"},
    entityManagerFactoryRef = "db2EntityManager",
    transactionManagerRef = "db2TransactionManager")
public class DB2_DataSource {
@Autowired
private Environment env;
@Bean
public LocalContainerEntityManagerFactoryBean db2EntityManager() {
    LocalContainerEntityManagerFactoryBean em
            = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource(db2Datasource());
    em.setPackagesToScan(
            new String[]{"com.onlinetutorialspoint.model.db2"});
    em.setPersistenceUnitName("db2EntityManager");
    HibernateJpaVendorAdapter vendorAdapter
            = new HibernateJpaVendorAdapter();
    em.setJpaVendorAdapter(vendorAdapter);
    HashMap<String, Object> properties = new HashMap<>();
    properties.put("hibernate.dialect",
            env.getProperty("hibernate.dialect"));
    properties.put("hibernate.show-sql",
            env.getProperty("jdbc.show-sql"));
    em.setJpaPropertyMap(properties);
    return em;
}
@Bean
public DataSource db2Datasource() {
    DriverManagerDataSource dataSource
            = new DriverManagerDataSource();
    dataSource.setDriverClassName(
            env.getProperty("jdbc.driver-class-name"));
    dataSource.setUrl(env.getProperty("db2.datasource.url"));
    dataSource.setUsername(env.getProperty("db2.datasource.username"));
    dataSource.setPassword(env.getProperty("db2.datasource.password"));
    return dataSource;
}
@Bean
public PlatformTransactionManager db2TransactionManager() {
    JpaTransactionManager transactionManager
            = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(
            db2EntityManager().getObject());
    return transactionManager;
}
}

My Rest Controller

@RestController
 public class CustomerController {
 @Autowired
 private PersonRepository personRepositorydb1;
 @Autowired
 private PersonRepository personRepositorydb2;

 @RequestMapping("/save")
 public Person savePersonDetails()
 public savePersonDetails(@RequestBody Person person ){
     personRepositorydb1.savePerson(person);
    return personRepositorydb2.savePerson(person);
}
}

If i call two repository means its getting error the model name is already impoted My Repository is

import com.onlinetutorialspoint.model.db1.Person;
@Repository
public interface PersonRepository extends CrudRepository<Person, Long>{
}

import com.onlinetutorialspoint.model.db2.Person;
@Repository
public interface PersonRepository extends CrudRepository<Person, Long>{
}

1 Answers1

0

Maybe you can use the same approach in this answer

Spring Data + JPA with multiple datasources but only one set of Repositories

Here there is an example on how to use AbstractRoutingDataSource

https://www.endpoint.com/blog/2016/11/16/connect-multiple-jpa-repositories-using

bora.oren
  • 3,439
  • 3
  • 33
  • 31
balax85
  • 36
  • 2
  • I need it in springboot – jebin hector Jan 27 '18 at 20:16
  • Yes, I understand and the link that I put can be replicated also in spring boot. Take a look on the dependencies imported into spring boot https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-dependencies/pom.xml The interface CrudRepository is from spring data, not from spring boot. Also the AbstractRoutingDataSource is from the core spring framework and it can be used with spring boot. I'm note sure if the link that I put can resolve your issue. – balax85 Jan 28 '18 at 13:48
  • I do a test here https://github.com/balax85/SpringProjectExample I add a new data source. Into the core module you can find two db connection in package it.balax85.examples.core.conf. I duplicate an existing repository named CommissionRepository that it is in it.balax85.examples.core.repository I add the same repository in it.balax85.examples.core.test (change the name, otherwise spring do not create two repository). The two repo are used into it.balax85.examples.core.dao.CommissionDao. I only checked that the changes can compile and run spring-boot but I haven't exception. Can you look? – balax85 Jan 28 '18 at 14:48
  • Note that the article mentioned above on how to use AbstractRoutingDataSource has moved to: https://www.endpointdev.com/blog/2016/11/connect-multiple-jpa-repositories-using/ – Jon Jensen Dec 05 '21 at 01:35