Updated April 3, 2023
Definition of Spring Boot Multiple Data Sources
In spring boot, we can configure multiple data sources which can help us to interact with the different databases. By the use of this, we can use different data sources depending upon the requirement. But to make this work in spring boot we must make a lot of configurations inside our application, we will see two data sources which we can configure inside our application and use for a different purpose, and we can store the object of these two different entities into different classes. In the section we will how we can implement this, what are the different configurations we need, and how it works internally for beginners to understand.
Syntax:
As we already know and discussed that it requires a lot of configuration to make this work, but here we will see some of the main annotations which will be required while using this inside the application
let’s get started with basic syntax for this.
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "db2EntityMgrFactory",
transactionManagerRef = "db2TransactionMgr",
basePackages = { "yor_base_package_name" })
@EnableTransactionManagement
As you can see in the above line of syntax, we are using different annotation here, to configure the multiple data sources of the application to work. Inside the base package, we can write our own base package for the repository which contains the JPA to interact with the persistence layer. Let’s take a look at the simple practice syntax for a better
understanding see below.
e.g.:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "db2EntityMgrFactory",
transactionManagerRef = "db2TransactionMgr",
basePackages = { "com.example.datasources.student.repository" })
@EnableTransactionManagement
As you can see, we have now specified the base package for the student entity that contains the repository. In the coming section, we will see the internal working of the other required configurations which is needed to make this work.
How to work with multiple data sources in Spring boot?
In this section, we will see what different configurations are required to make this work. Also, we will have a look at the internal working for this let’s get started,
First, we will see what are the different annotations which we are going to use in this example see below.
1) @EnableJpaRepositories: This annotation tells the spring boot about the data source of the repository to be used. Inside this annotation, we have a different attribute which we need to mention while using it. one of the main attributes is ‘basePackages’ which will let us define the base package for the repository, this package is very much mandatory to mention otherwise we may receive many errors while running the application while initializing the bean.
2) db1EntityMgrFactory(): This is one of the main attributes for the @EnableJpaRepositories while configuring it we need to mention this property as well, this attribute is responsible to create the instance of LocalContainerEntityManagerFactoryBean which will be needed by the data source.
3) db1TransactionMgr(): This is another attribute for the @EnableJpaRepositories, this is also required while using or configuring the data source for the application.
This attribute is responsible to create the inside of PlatformTransactionManager for data source which is required to handle the transaction management or transaction-related part.
4) dataSource(): we also have one more method, and this is a very important one also. This method will always be annotated with the @ConfigurationProperties, this annotation further contains one prefix property or attribute we can say which will help or tell the data source about the prefix property and will be helpful while creating the instance of the data source.
Examples
Now we will see one example of what needs to be configured while using the multiple data sources for our spring boot application let’s get started.
1) The first step that we need to take up is to create the spring boot application by using the spring initializer. Go to the below URL and fill in all the required details and generate
the project and import it inside any editor of your choice.
URL:
https://start.spring.io/
2) Second step is to add one more dependency which is spring-data, this will help us to interact with the persistence layer of the application, below see the required dependency to be added;
e.g.:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
3) Step three is to add configuration dependency for using the @ConfigurationProperties annotation inside the application, this is also important to add else we will not be able to
configure the data source properly see below.
e.g.:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
4) Now we need to add the h2 database dependency, for the demo purpose for multiple data sources see below;
e.g.:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
5) Now we will create a different configuration file for the data source which will configure the data source for us. Also, inside this class we will use all the required
annotations which we have discussed in the above part, let; e take a look at the code now see below;
e.g.:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "db1EntityMgrFactory",
transactionManagerRef = "db1TransactionMgr",
basePackages = {
"com.exmaple.datasource.student.repo"
})
@EnableTransactionManagement
public class StudentConfig {
@Bean(name = "db1EntityMgrFactory")
@Primary
public LocalContainerEntityManagerFactoryBean db1EntityMgrFactory(
final EntityManagerFactoryBuilder builder,
@Qualifier("datasource1") final DataSource dataSource) {
final Map<String, String> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", "create-drop");
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return builder
.dataSource(dataSource)
.properties(properties)
.packages("com.springboot.multiple.datasources.model")
.persistenceUnit("student")
.build();
}
@Bean(name = "datasource1")
@ConfigurationProperties(prefix = "spring.db1.datasource")
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db1TransactionMgr")
@Primary
public PlatformTransactionManager db1TransactionMgr(
@Qualifier("db1EntityMgrFactory") final EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
This is the configuration we need to configure the datasouce path. here if you can see we have also used the model name here and most important the @Primary annotation which will tell spring that it is the primary data source for the application. Also, this class will initialize all the required beans for us, because we have annotate them with
@Configuration also.
6) Now in this step we will create the same class as above, but the base package and model name will be different for this. Now we will configure the entity for ’employee’
entity. This will give the data source for the employee repository. let’s look at the configuration see below.
e.g.:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "db2EntityMgrFactory",
transactionManagerRef = "db2TransactionMgr",
basePackages = {
"com.example.datasource.employee.repo"
})
@EnableTransactionManagement
public class EmployeeConfig {
@Bean(name = "db2EntityMgrFactory")
public LocalContainerEntityManagerFactoryBean db2EntityMgrFactory(
final EntityManagerFactoryBuilder builder,
@Qualifier("datasource2") final DataSource dataSource) {
final Map<String, String> properties = new HashMap<>();
properties.put("hibernate.hbm2ddl.auto", "create-drop");
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
return builder
.dataSource(dataSource)
.properties(properties)
.packages("com.springboot.multiple.datasources.model")
.persistenceUnit("employee")
.build();
}
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "spring.db2.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db2TransactionMgr")
public PlatformTransactionManager db2EntityMgrFactory(
@Qualifier("db2EntityMgrFactory") final EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
This is the configuration for the ’employee’ class, also we have changed the repository path for this data source if you do not mention the basepackage it will not work and give an error while running the application. Run the application and you will see the below output without errors;
Conclusion
It is easy to configure but we just need to maintain the different configuration file for all the data sources and need to define the primary one also. But requires less time do to and is easy to handle and is stable by the developers.
Recommended Articles
This is a guide to Spring Boot Multiple Data Sources. Here we discuss the definition, syntax, How to work with multiple data sources in Spring boot? examples with code implementation. You may also have a look at the following articles to learn more –