Home » Framework » How to configure Multiple Mongodb in Spring Boot

How to configure Multiple Mongodb in Spring Boot

This article explains how to configure multiple MongoDB in the Spring Boot application. Here I used the mongo template to configure multiple MongoDB setups. Let see how the configuration is done.

Before configuring multiple MongoDB setups we should know about the single MongoDB set up in the Spring Boot application. If you want to know about MongoDB setup with spring boot then please take a look at Spring Boot with MongoDB.

Actually, the mongo repository is useful when we go for multiple MongoDB setups. But in this project, I used the mongo template to configure that because most of us using the mongo template in projects for handling complex queries.

So this article is very useful for those who want to configure multiple MongoDB by using the mongo template.

Let start to see the implementation. First, we need to create the spring boot project in Spring Initializr with the needed dependencies. The dependencies are mentioned in the pom.xml file below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.10.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.tipstocode</groupId>
	<artifactId>springbootmulitplemongodb</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>springbootmulitplemongodb</name>
	<description>Spring Boot With Multiple MongoDB Setup</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-mongodb</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

The entire project structure shown below.

Multple-Mongodb-Setup

Multiple MongoDB Configurations

Let's move to the configuration part. we need to mention the multiple mongo DB properties in the application.properties file. Here I used two MongoDB named first_db and second_db. The configuration file is below

application.properties file

#First DB configuration
#firstdb.config.username=tipstocode
#firstdb.config.password=12345
firstdb.config.database=first_db
firstdb.config.port=27017
firstdb.config.host=localhost

#Second DB configuration
#seconddb.config.username=tipstocode
#seconddb.config.password=12345
seconddb.config.database=second_db
seconddb.config.port=27017
seconddb.config.host=localhost

Now we start to write the configuration part. First, we have to create an abstract class which will handle multiple MongoDB setup. This class is used to create MongoDB factory which is common to all the databases we configured.

In this abstract class, we can establish multiple connections and create multiple mongo templates with the properties host, database, and port with the help of the factory method.

package com.tipstocode.multiplemongodb.configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import com.mongodb.MongoClient;

public abstract class AbstractMongoDBConfiguration {
    //Mongo DB Properties    
    private String host;    
    private String database;    
    private int port;

        public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public String getDatabase() {
		return database;
	}
	public void setDatabase(String database) {
		this.database = database;
	}
	public int getPort() {
		return port;
	}
	public void setPort(int port) {
		this.port = port;
	}
	//**This method is used to create MongoDb Factory which is common to all databases
    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(host, port), database);
    }     
    //**Create MongoTemplate using Factory Method
    abstract public MongoTemplate getMongoTemplate() throws Exception;
}

Then we have to create the class with the configuration of Mongo DB's we used. First, we have to configure the first MongoDB. The configuration class is below.

package com.tipstocode.multiplemongodb.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.core.MongoTemplate;
@Configuration 
@ConfigurationProperties(prefix = "firstdb.config") //This prefix points to first_db properties. Please check application.properties
public class FirstDBConfig extends AbstractMongoDBConfiguration {   
    @Primary
    @Override
    @Bean(name = "firstDBMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Please make sure the prefix is used at @ConfigurationProperties and application.properties file are the same. if you see the application.properties file I used the prefix 'firstdb' here also I used the same.

we have to create a bean with the name of 'firstDBMongoTemplate'. This is the template of first_db. Likewise, we have to create the configuration for the second MongoDB. The configuration for the same is below.

package com.tipstocode.multiplemongodb.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
@Configuration
@ConfigurationProperties(prefix = "seconddb.config") //This prefix points to second_db properties. Please check application.properties
public class SecondDBConfig extends AbstractMongoDBConfiguration{    
    @Bean(name = "secondDBMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Yes, now the configuration part is over. Now we have to create separate connection classes for both MongoDB. This class creates the different mongo templates for different MongoDB. The classes are below

First Database Connection

package com.tipstocode.multiplemongodb.connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;

public class FirstDBConnection {	
	@Autowired	
	@Qualifier("firstDBMongoTemplate") 
	private MongoTemplate mongoTemplate;	
	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}
	public void setMongoTemplate(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}	
	//This method is used to check whether mongoTemplate is created or not
	protected void checkDaoConfig() throws IllegalArgumentException {
		if (this.mongoTemplate == null) {
			throw new IllegalArgumentException("'mongoTemplate' is required");
		}
	}
}

Second Database Connection

package com.tipstocode.multiplemongodb.connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;

public class SecondDBConnection{	
	@Autowired	
	@Qualifier("secondDBMongoTemplate") 
	private MongoTemplate mongoTemplate;	

	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}
	public void setMongoTemplate(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}	
	//This method is used to check whether mongoTemplate is created or not
	protected void checkDaoConfig() throws IllegalArgumentException {
		if (this.mongoTemplate == null) {
			throw new IllegalArgumentException("'mongoTemplate' is required");
		}
	}
}

In the @Qualifier annotation, we have to mention the bean name properly that we created in the bean configurations above. Now all the configurations are over.

Create Controller with Rest API

Now, let's start to create controller, manager, and DAO classes for executing save operation. The flow will be like the API call reaches the controller then moves to manager and moves to the DAO operations separately.

Controller Class

package com.tipstocode.multiplemongodb.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tipstocode.multiplemongodb.firstdb.model.FirstModel;
import com.tipstocode.multiplemongodb.manager.Manager;
import com.tipstocode.multiplemongodb.seconddb.model.SecondModel;

@RestController
public class Controller {
	
@Autowired
Manager manager;
	
//save 'FirstModel' collection to 'first_db' database
@RequestMapping(value = "/savefirstmodel", method = RequestMethod.POST )
public ResponseEntity<String> saveFirstModel(@RequestBody FirstModel firstModel) {		
		manager.saveFirstModel(firstModel);		
		return new ResponseEntity<String>("Saved", HttpStatus.OK);
}	

//save 'SecondModel' collection to 'second_db' database
@RequestMapping(value = "/savesecondmodel", method = RequestMethod.POST )
public ResponseEntity<String> saveSecondModel(@RequestBody SecondModel secondModel) {		
		manager.saveSecondModel(secondModel);		
		return new ResponseEntity<String>("Saved", HttpStatus.OK);
}
}

Manager Interface and Manager Implementation

package com.tipstocode.multiplemongodb.manager;
import com.tipstocode.multiplemongodb.firstdb.model.FirstModel;
import com.tipstocode.multiplemongodb.seconddb.model.SecondModel;

public interface Manager {
	void saveFirstModel(FirstModel firstModel);
	void saveSecondModel(SecondModel secondModel);
}
package com.tipstocode.multiplemongodb.manager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.tipstocode.multiplemongodb.dao.FirstDBDAO;
import com.tipstocode.multiplemongodb.dao.SecondDBDAO;
import com.tipstocode.multiplemongodb.firstdb.model.FirstModel;
import com.tipstocode.multiplemongodb.seconddb.model.SecondModel;

@Component
public class ManagerImpl implements Manager{
	
@Autowired	
FirstDBDAO firstDBDAO;
	
@Autowired
SecondDBDAO secondDBDAO;
@Override
public void saveFirstModel(FirstModel firstModel) {
	// TODO Auto-generated method stub
	firstDBDAO.saveFirstModel(firstModel);
}
@Override
public void saveSecondModel(SecondModel saveSecondModel) {
	// TODO Auto-generated method stub
	secondDBDAO.saveSecondModel(saveSecondModel);
}
}

DAO Interface and DAO Implementation

There are two DAO implementation classes extends with the corresponding connections classes to create the mongo template respectively.

package com.tipstocode.multiplemongodb.dao;
import com.tipstocode.multiplemongodb.firstdb.model.FirstModel;

public interface FirstDBDAO {
	void saveFirstModel(FirstModel firstModel);	
}
package com.tipstocode.multiplemongodb.dao;
import org.springframework.stereotype.Repository;
import com.tipstocode.multiplemongodb.connection.FirstDBConnection;
import com.tipstocode.multiplemongodb.firstdb.model.FirstModel;

@Repository
public class FirstDBDAOImpl extends FirstDBConnection implements FirstDBDAO{
@Override
public void saveFirstModel(FirstModel firstModel) {
	// TODO Auto-generated method stub
	//**This mongoTemplate is a reference of first_db created from //FirstDBConnection
		getMongoTemplate().save(firstModel);
}
}
package com.tipstocode.multiplemongodb.dao;
import com.tipstocode.multiplemongodb.seconddb.model.SecondModel;

public interface SecondDBDAO {
	void saveSecondModel(SecondModel saveSecondModel);
}
package com.tipstocode.multiplemongodb.dao;
import org.springframework.stereotype.Repository;
import com.tipstocode.multiplemongodb.connection.SecondDBConnection;
import com.tipstocode.multiplemongodb.seconddb.model.SecondModel;

@Repository
public class SecondDBDAOImpl extends SecondDBConnection implements SecondDBDAO{	
@Override
public void saveSecondModel(SecondModel saveSecondModel) {
	// TODO Auto-generated method stub
	//**This mongoTemplate is a reference of second_db created from //SecondDBConnection
		 getMongoTemplate().save(saveSecondModel);
}
}

For testing, I have created two models named as FirstModel and SecondModel. The FirstModel collection belongs to first_db and the SecondModel collection belongs to second_db. While we perform the save operation both the collections are saved in their corresponding databases.

FirstModel Class

package com.tipstocode.multiplemongodb.firstdb.model;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "first_model")
public class FirstModel {		
	@Id
	private ObjectId _id;		
	private String firstName;	
	private String lastName;

//Getters and Setters are here
}

SecondModel Class

package com.tipstocode.multiplemongodb.seconddb.model;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "second_model")
public class SecondModel {	
	@Id
	private ObjectId _id;		
	private String emailId;	
	private String mobile;

//Getters and Setters are here
}

Everything is finished. Now, let's start to test the API in postman.

Save FirstModel collection into first_db

Rest API : http://localhost:8080/springbootmulitplemongodb/savefirstmodel

Method : POST

Content Type : Application/Json

First Model

Save SecondModel collection into second_db

Rest API : http://localhost:8080/springbootmulitplemongodb/savefirstmodel

Method : POST

Content Type : Application/Json

Second Model

Download the full source code from GitHub.

I Hope this article is useful. If any clarification please mention it in the comments section below.

Leave a Reply

Your email address will not be published. Required fields are marked *