JavaSpringTechnology

Spring Boot Multiple MongoTemplates

This tutorial covers How to Create Multiple MongoTemplates in a Spring Boot Application.

Overview

In this post we are going to talk about creating multiple Mongo Templates in a Spring Boot backed application. Spring Boot helps us concentrate on our business logic while it takes care of all the application related configurations. Spring Boot’s powerful auto configuration help us writing our applications very fast.

We will begin with understanding How Spring Boot creates Mongo Connection before we dive into creating multiple MongoTemplates.

How Spring Boot Creates a Mongo Connection

In order to create a MongoTemplate instance, we need to provide the connection details using Spring Application Properties or Yaml files.

spring.data.mongodb.host= <HOST_NAME>
spring.data.mongodb.port= <PORT_NUMBER>
spring.data.mongodb.uri= <MONGO_URI>

Next Spring boot will automatically detects the configuration and makes connection to the database. Also, Spring Boot creates MongoTemplate which is a wrapper class for the MongoDB Connection.

To do that, first Spring Boot loads the MongoDB related properties into a class called as MongoProperties. Next a class MongoDataAutoConfiguration uses the properties to create MongoTemplate instance using factory methods.

In order to create Multiple MongoDB Templates, we need to override these classes and customise their behaviour. Which is explained in the next section.

Create Multiple MongoTemplates

In order to customise MongoTemplate auto configuration, fist we will slightly modify the properties file.

As we have two different databases to connect to, we need to hold configurations for both databases.

primary.mongodb.host=<primary_mongodb_host>
primary.mongodb.port=<primary_mongodb_port>
primary.mongodb.database=<primary_mongodb_database>


secondary.mongodb.host=<secondary_mongodb_host>
secondary.mongodb.port=<secondary_mongodb_port>
secondary.mongodb.database=<secondary_mongodb_database>

Note that the prefix primary and secondary helps identifying both of our databases.

AbstractMongoConfig.java

Next, we create an abstract AbstractMongoConfig class. We will create two subclasses one for each database.

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

    //Setter methods go here..     

    /*      
     * Method that creates MongoDbFactory     
     * Common to both of the MongoDb connections     
     */
    public MongoDbFactory mongoDbFactory() throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(host, port), database);
    }

    /*     
     * Factory method to create the MongoTemplate     
     */
    abstract public MongoTemplate getMongoTemplate() throws Exception;
}

PrimaryMongoConfig.java

For our primary database, we will extend the abstract class we created.

@Configuration
@ConfigurationProperties(prefix = "primary.mongodb")
public class PrimaryMongoConfig extends AbstractMongoConfig {
    @Primary
    @Override
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Note that, this class loads all the properties which are prefixed with primary.mongodb. The actual instance fields reside in the parent class.

The factory method getMongoTemplate is marked as @Bean with a name. Also, we have marked the method with @Primary. Because of that when a bean tries to autowire MongoTemplate without specifying primary or secondary the primary mongo template is wired.

SecondaryMongoConfig.java

Similar to the previous one we will create another subclass for the secondary MongoDB database.

@Configuration
@ConfigurationProperties(prefix = "secondary.mongodb")
public class SecondaryMongoConfig extends AbstractMongoConfig {
    
    @Override public 
    @Bean(name = "secondaryMongoTemplate")
    MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

Note that the property source prefix we use here is secondary.mongodb. Also, we have marked the factory method with @Bean providing an appropriate name.

Autowiring Both MongoTemplates

We are done with customising the creation of two MongoTemplate instances.

Autowire Primary MongoInstance

@Autowired
@Qualifier(value = "primaryMongoTemplate")
protected MongoTemplate mongoTemplate;

Note that the Qualifier is optional here. That is because, we have marked the primary mongo template is @Primary.

Autowire Secondary MongoTemplate

@Autowired
@Qualifier(value = "secondaryMongoTemplate")
protected MongoTemplate mongoTemplate;

Summary

In this quick tutorial we have covered a practical example of creating Multiple MongoTemplates in Spring Boot Application. For more on Spring Boot visit Introduction To Spring Boot.