DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Authorization: Get It Done Right, Get It Done Early
  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud

Trending

  • Authorization: Get It Done Right, Get It Done Early
  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud
  1. DZone
  2. Coding
  3. Frameworks
  4. Multiple MongoDB Connectors With Spring Boot

Multiple MongoDB Connectors With Spring Boot

Let's take a look at a tutorial that explains how to build an application that connects to multiple MongoDBs. Also look at creating the data model and repositories.

Marcos Barbero user avatar by
Marcos Barbero
CORE ·
Oct. 03, 18 · Tutorial
Like (3)
Save
Tweet
Share
64.22K Views

Join the DZone community and get the full member experience.

Join For Free

This tutorial will guide you in the process to connect to multiple MongoDBs.

What You Will Build

You will build an application that connects to multiple MongoDBs.

Prerequisites

  • JDK 1.8
  • Text editor or your favorite IDE
  • Maven 3.0+
  • MongoDB

The sample project uses Project Lombok to generate getters, setters, contructors, etc.

Spring Boot MongoDB Connection

To create a MongoTemplate instance through Spring Boot, we only need to provide Mongo Server details in Spring Boot specific property keys and Spring Boot on startup automatically creates a Mongo Connection with MongoTemplate wrapper and lets us auto wire wherever we want to use.

Below are the basic properties required for creating a MongoTemplate.

spring:
  data.mongodb:
    host: # hostname
    port: # port
    uri: #uri
    database: #db

Spring Boot has a class called MongoProperties.java, which defines the mandatory property key prefix as spring.data.mongodb (can be seen in the above properties extract). The MongoProperties.java holds all the mongo properties that we wrote in the application.yml. Then there is another class called as MongoDataAutoConfiguration.java which uses the MongoProperties.java as its Properties Configuration Class and is responsible for actually creating the MongoTemplate through one of its factory methods.

To connect to two different mongo servers, it’s required to override all these classes and their behaviors.

Disabling Spring Boot AutoConfig

To be able to create multiple MongoTemplate objects, it’s necessary to disable the Spring Boot autoconfig for MongoDB. It can be achieved just by adding the following property in the application.yml file.

spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration

Configuring Multiple MongoTemplates

First of all, create the following @ConfigurationProperties class.

src/main/java/com/marcosbarbero/wd/multiplemongo/config/MultipleMongoProperties

import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;

import lombok.Data;

@Data
@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {

    private MongoProperties primary = new MongoProperties();
    private MongoProperties secondary = new MongoProperties();
}

And then add the following properties in the application.yml

mongodb:
  primary:
    host: localhost
    port: 27017
    database: second
  secondary:
    host: localhost
    port: 27017
    database: second

Now it’s necessary to create the MongoTemplates to bind the given configuration in the previous step.

src/main/java/com/marcosbarbero/wd/multiplemongo/config/MultipleMongoConfig

package com.marcosbarbero.wd.multiplemongo.config;

import com.mongodb.MongoClient;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties(MultipleMongoProperties.class)
public class MultipleMongoConfig {

    private final MultipleMongoProperties mongoProperties;

    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate() throws Exception {
        return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
    }

    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() throws Exception {
        return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
    }

    @Bean
    @Primary
    public MongoDbFactory primaryFactory(final MongoProperties mongo) throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
                mongo.getDatabase());
    }

    @Bean
    public MongoDbFactory secondaryFactory(final MongoProperties mongo) throws Exception {
        return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
                mongo.getDatabase());
    }

}

With the configuration above, you’ll be able to have two different MongoTemplates based on the custom configuration properties that we provided previously in this guide.

Using Multiple Templates

In the previous step, we created two MongoTemplates, primaryMongoTemplate and secondaryMongoTemplate. In this section, we’ll make some data model and make it all work together.

Creating the Data Model and Repositories

First, we will create two data models to access different collections.

src/main/java/com/marcosbarbero/wd/multiplemongo/repository/primary/PrimaryModel

package com.marcosbarbero.wd.multiplemongo.repository.primary;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "first_mongo")
public class PrimaryModel {

@Id
private String id;

private String value;

@Override
public String toString() {
        return "PrimaryModel{" + "id='" + id + '\'' + ", value='" + value + '\''
+ '}';
}
}

src/main/java/com/marcosbarbero/wd/multiplemongo/repository/secondary/SecondaryModel

package com.marcosbarbero.wd.multiplemongo.repository.secondary;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "second_mongo")
public class SecondaryModel {

    @Id
    private String id;

    private String value;

    @Override
    public String toString() {
        return "SecondaryModel{" + "id='" + id + '\'' + ", value='" + value + '\''
                + '}';
    }
}

Now we’ll need to create one repository per data model.

src/main/java/com/marcosbarbero/wd/multiplemongo/repository/primary/PrimaryRepository

package com.marcosbarbero.wd.multiplemongo.repository.primary;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface PrimaryRepository extends MongoRepository<PrimaryModel, String> {

}

src/main/java/com/marcosbarbero/wd/multiplemongo/repository/secondary/SecondaryRepository

package com.marcosbarbero.wd.multiplemongo.repository.secondary;

import org.springframework.data.mongodb.repository.MongoRepository;

public interface SecondaryRepository extends MongoRepository<SecondaryModel, String> {

}

Enabling Mongo Repositories

Now, we already have the properties configuration classes and data model classes, so we need to configure which MongoTemplate will be responsible for each defined repository.

src/main/java/com/marcosbarbero/wd/multiplemongo/config/PrimaryMongoConfig

package com.marcosbarbero.wd.multiplemongo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.marcosbarbero.wd.multiplemongo.repository.primary",
        mongoTemplateRef = "primaryMongoTemplate")
public class PrimaryMongoConfig {

}

src/main/java/com/marcosbarbero/wd/multiplemongo/config/SecondaryMongoConfig

package com.marcosbarbero.wd.multiplemongo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.marcosbarbero.wd.multiplemongo.repository.secondary",
        mongoTemplateRef = "secondaryMongoTemplate")
public class SecondaryMongoConfig {

}

Running

To test the application, I just added the following code to the main class in the project.

src/main/java/com/marcosbarbero/wd/multiplemongo/Application

package com.marcosbarbero.wd.multiplemongo;

import com.marcosbarbero.wd.multiplemongo.repository.primary.PrimaryModel;
import com.marcosbarbero.wd.multiplemongo.repository.primary.PrimaryRepository;
import com.marcosbarbero.wd.multiplemongo.repository.secondary.SecondaryModel;
import com.marcosbarbero.wd.multiplemongo.repository.secondary.SecondaryRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@SpringBootApplication
public class Application implements CommandLineRunner {

    @Autowired
    private PrimaryRepository primaryRepository;

    @Autowired
    private SecondaryRepository secondaryRepository;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("************************************************************");
        log.info("Start printing mongo objects");
        log.info("************************************************************");
        this.primaryRepository.save(new PrimaryModel(null, "Primary database plain object"));

        this.secondaryRepository.save(new SecondaryModel(null, "Secondary database plain object"));

        List<PrimaryModel> primaries = this.primaryRepository.findAll();
        for (PrimaryModel primary : primaries) {
            log.info(primary.toString());
        }

        List<SecondaryModel> secondaries = this.secondaryRepository.findAll();

        for (SecondaryModel secondary : secondaries) {
            log.info(secondary.toString());
        }

        log.info("************************************************************");
        log.info("Ended printing mongo objects");
        log.info("************************************************************");

    }
}

As this project was built using Spring Boot, to run it, just execute the following commands:

Build

$ ./mvnw clean package

Run

$ java -jar target/multiple-mongo-connectors-0.0.1-SNAPSHOT.jar

The process prints the following output:

************************************************************
Start printing mongo objects
************************************************************
Opened connection [connectionId{localValue:3, serverValue:11}] to localhost:27017
Opened connection [connectionId{localValue:4, serverValue:12}] to localhost:27017
PrimaryModel{id='5a8834ee536b1d604345da4e', value='Primary database plain object'}
SecondaryModel{id='5a884cc8536b1da4468466a7', value='Secondary database plain object'}
************************************************************
Ended printing mongo objects
************************************************************

This guide requires a MongoDB instance up and running in localhost and 27017port.

Summary

Congratulations! You just created a Spring Boot project that connects to multiple MongoDB instances.

Footnote

  • The code used for this tutorial can be found on GitHub.
Spring Framework Spring Boot MongoDB

Published at DZone with permission of Marcos Barbero, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Authorization: Get It Done Right, Get It Done Early
  • Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
  • Transactional Outbox Patterns Step by Step With Spring and Kotlin
  • How To Integrate Microsoft Team With Cypress Cloud

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: