DEV Community

Cover image for How To Configure Multiple MongoDB Connectors in Spring Boot
Antonello Zanini for Writech

Posted on • Updated on

How To Configure Multiple MongoDB Connectors in Spring Boot

There are plenty of online guides explaining how to configure a Spring Boot application that connects to multiple MongoDBs. The common approach was to use MongoDbFactory, but this class was deprecated in Spring Data MongoDB 3.x, which introduced the MongoDB 4.x driver.

So, let's see how to configure multiple MongoDB data sources in Spring Boot using Spring Data MongoDB 3.x.

Please note that code will be written in Kotlin, but the same result can be achieved in Java as well. Similarly, I am going to use only two different MongoDB connections in this tutorial, but the approach works with any number of databases.

Adding the Required Dependencies

First, you need to add spring-boot-starter-data-mongodb to your project's dependencies. Use at least the 2.3.0 version since the MongoDB Driver 4.x was introduced in Spring Boot Starter Data MongoDB 2.3.0.RELEASE.

If you are a Gradle user, add this dependency to your project's build file:

compile "org.springframework.boot:spring-boot-starter-data-mongodb:2.3.0.RELEASE"
Enter fullscreen mode Exit fullscreen mode

Otherwise, if you are a Maven user, add the following dependency to your project's build POM:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
    <version>2.3.0.RELEASE</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Now, you have all you need to use MongoDB in Spring Boot.

Defining Multiple MongoTemplate Instances

If you already have multiple MongoTemplates but you want to upgrade to Spring Data MongoDB 3.x, I recommend reading the docs first. Otherwise, you can start from scratch by following the next few steps.

First, you need to define all your MongoDB connection details in your application.properties file.

The host and port configurations are no longer supported in the MongoDB 4.x driver, so you need to use a single URI providing all the required configurations with this format:

mongodb://<username>:<password>@<host>:<port>/<db_name>
Enter fullscreen mode Exit fullscreen mode

Please note that <username>:<password>@ is optional and you should only use it for authenticated connections.

So, your application.properties should contain something like this:

#--- Primary MongoDB ---#
spring.data.mongodb.uri=mongodb://admin:password@127.0.0.1:27017/primary
#--- Secondary MongoDB ---#
mongodb.uri=mongodb://admin:password@127.0.0.1:27017/secondary
Enter fullscreen mode Exit fullscreen mode

Now, it is time to add a new Spring Boot configuration file in which you will define a MongoTemplate Spring Boot bean for each connection:

@Configuration
class MultipleMongoConfig {
    @Primary
    @Bean(name = ["primaryMongoProperties"])
    @ConfigurationProperties(prefix = "spring.data.mongodb")
    fun getPrimary() : MongoProperties {
        return MongoProperties()
    }

    @Bean(name = ["secondaryMongoProperties"])
    @ConfigurationProperties(prefix = "mongodb")
    fun getSecondary() : MongoProperties {
        return MongoProperties()
    }

    @Primary
    @Bean(name = ["primaryMongoTemplate"])
    fun primaryMongoTemplate() : MongoTemplate {
        return MongoTemplate(primaryMongoDatabaseFactory(getPrimary()))
    }

    @Bean(name = ["secondaryMongoTemplate"])
    fun secondaryMongoTemplate() : MongoTemplate {
        return MongoTemplate(secondaryMongoDatabaseFactory(getSecondary()))
    }

    @Primary
    @Bean
    fun primaryMongoDatabaseFactory(mongo : MongoProperties) : MongoDatabaseFactory {
        return SimpleMongoClientDatabaseFactory(
            mongo.uri
        )
    }

    @Bean
    fun secondaryMongoDatabaseFactory(mongo : MongoProperties) : MongoDatabaseFactory {
        return SimpleMongoClientDatabaseFactory(
            mongo.uri
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

The @ConfigurationProperties annotation works with hierarchical properties that all have the same prefix defined in your configuration file.

Spring Boot will automatically bind any property defined in the application.properties file that has the prefix declared in the annotation and the same name as one of the fields in the target class. This means that the uri field of the MongoProperties objects will have the value read from your configuration file.

The MongoProperties instances are used to establish the connections to the databases through SimpleMongoClientDatabaseFactory and then create the required MongoTemplate instances.

The MongoTemplate class is the primary implementation of the MongoOperations interface and provides a basic set of MongoDB operations. You can use a MongoTemplate object to do aggregations, sorting, and to find the desired documents based on multiple criteria in the database it refers to.

Lastly, you have to disable Spring Boot autoconfiguration for Mongo. You can achieve this by adding these lines of code on top of your Spring Boot application's main class:

@SpringBootApplication(exclude = [
   MongoAutoConfiguration::class,
   MongoDataAutoConfiguration::class
])
Enter fullscreen mode Exit fullscreen mode

Using the MongoTemplate Instances

Using MongoTemplate directly

MongoTemplate provides a basic API to the underlying persistence engine and can be used to execute queries. All you need to use it in such a way is a working instance.

Let's assume you want to retrieve all the authors saved in a collection named authors placed in the secondary MongoDB database by a specific surname.

Now, you need an Author class annotated with @Document representing the documents stored in the collection:

@Document(collection = "author")
class Author {
    @get:Id
    @get:Field("_id")
    var id: String? = null

    @get:Field("name")
    var name: String? = null

    @get:Field("surname")
    var surname: String? = null
}
Enter fullscreen mode Exit fullscreen mode

Then, in a DAO layer class, you can define the retrieving logic as follows:

@Repository
class AuthorDao {
    @Autowired
    @Qualifier("secondaryMongoTemplate")
    protected lateinit var secondaryMongoTemplate : MongoTemplate

    fun findBySurname(surname): List<Author> {
        val query = Query()

       query.addCriteria(
           Criteria.where("surname").`is`(surname)
       )
       return secondaryMongoTemplate.find(query, Author::class.java)
    }
}
Enter fullscreen mode Exit fullscreen mode

Notice that the @Qualifier annotation is required to select the desired MongoTemplate instance by Bean name. Without it, Spring Boot would choose the primaryMongoTemplate object defined in MultipleMongoConfig because it is marked with @Primary.

Et voilà! No other lines of code are required.

Using MongoTemplate Through MongoRepository

Repositories are one of the main concepts of Spring Data and a way to reduce the effort to implement data access layers by avoiding boilerplate code. For further reading, I recommend the docs.

The implementation class of MongoRepository harnesses a MongoTemplate instance at runtime.

To specify which MongoTemplate bean has to be used, you need extra configurations. In particular, you have to define a new @Configuration file for each MongoTemplate instance.

This is what the configuration file to enable repositories working with primaryMongoTemplate looks like:

@Configuration
@EnableMongoRepositories(
    basePackages = ["com.example.yourproject.primary.repositories"],
    mongoTemplateRef = "primaryMongoTemplate"
)
class PrimaryMongoDBRepositoryConfig
Enter fullscreen mode Exit fullscreen mode

And this is what the configuration file to enable repositories to work with secondaryMongoTemplate looks like:

@Configuration
@EnableMongoRepositories(
    basePackages = ["com.example.yourproject.secondary.repositories"],
    mongoTemplateRef = "secondaryMongoTemplate"
)
class SecondarMongoDBRepositoryConfig
Enter fullscreen mode Exit fullscreen mode

Please, note that basePackages must point to the packages where all your repositories related to a specific mongoTemplateRef are placed.

Now you have all you need to start using MongoDB repositories in Spring Boot. This article is not aimed at showing that and I suggest reading the docs instead.

Conclusion

In today's article, we looked at how to define multiple MongoTemplates using the MongoDB 4.x driver in Spring Boot from the ground up. At the same time, I showed how to use them directly or through MongoRepository to execute all the queries you need to retrieve and persist data.

Thanks for reading! I hope that you found this article helpful.


The post "How To Configure Multiple MongoDB Connectors in Spring Boot" appeared first on Writech.

Top comments (0)