Spring Boot Integration with MongoDB Tutorial

In this tutorial we'll use Spring Boot to access data from a MongoDB Atlas cluster. To follow along you'll need to sign in to MongoDB Atlas.

Spring Boot is an auto-configured microservice-based web framework that provides built-in features for security and database access.

With Spring boot, we can quickly create stand-alone applications without having to make too many configuration changes (as we will see later). MongoDB is the most popular NoSQL database because of the ease with which data can be stored and retrieved. Combining Spring Boot and MongoDB results in applications that are fast, secure, reliable, and require minimum development time.

This tutorial demonstrates how we can integrate Spring Boot with MongoDB using the Spring Data MongoDB API.

How to Use Spring Boot with MongoDB

Spring Boot creates quick production-ready applications. MongoDB and Spring Boot interact using the MongoTemplate class and MongoRepository interface.

  • MongoTemplate — MongoTemplate implements a set of ready-to-use APIs. A good choice for operations like update, aggregations, and others, MongoTemplate offers finer control over custom queries.
  • MongoRepository — MongoRepository is used for basic queries that involve all or many fields of the document. Examples include data creation, viewing documents, and more.

Spring Boot MongoDB configuration using both approaches needs only a few lines of code.

Getting Started with MongoDB and Spring Boot

Spring is an application framework for Java web applications. It is based on the MVC (Model-View-Controller) framework. Spring’s dependency injection handles features like database access, security, initialization, and so on, so that developers can focus on the business logic.

Spring Boot is built on top of the Spring framework mainly for REST APIs. Spring Boot requires very few configurations. It has four layers:

  • Presentation layer — The view part of the MVC framework that handles the front-end.
  • Business layer — The controller where all the business logic and validations are done.
  • Persistence layer — This layer translates the business objects to database objects.
  • Database layer — The actual CRUD (Create, Read, Update, Delete) operations happen here.

MongoDB is fast and can handle large amounts of structured and unstructured data, making it a database of choice for web applications. The Spring framework provides powerful connectors to easily perform database operations with MongoDB. Data is stored as BSON objects in MongoDB making data retrieval easy.

For this Spring Boot and MongoDB example tutorial, we are only concerned with the Persistence and Database layers. We want to keep the focus on CRUD operations, so we will run our program from an Integrated Development Environment (IDE). We will add Spring Boot MongoDB configurations to connect Spring Boot and MongoDB.

What We Will Build

Let us create a hypothetical grocery shopping list for a user. We will do the following operations:

  • In our Spring application, we define a grocery item Plain Old Java Object (POJO) with ID, name, quantity, and category.
  • Next, we perform create, read, update, and delete (CRUD) operations using MongoRepository public interface.
  • Finally, we show an alternate approach for updating documents using the MongoTemplate class.

Read our article Getting started with MongoDB and Java to learn more about POJO and MongoDB documents mapping.

What We Need

We need

The first step is to create the Spring Boot project using Spring Initializr with the following settings:

Spring Initializr Project settings like metadata, dependencies, Java version, etc.

Select Maven Project with language as Java (8) and Spring Boot version 2.5.3. Also, add dependencies — we have added Spring Web and Spring Data MongoDB. Spring Web embeds Apache Tomcat server, REST, and Spring MVC in your application, managing all the common dependencies at one place.

We use Spring Data MongoDB dependency to access the data from our MongoDB Atlas cluster in this application.

Enter the project metadata (as shown in the image above) and select the JAR option. Using Spring Initializr takes care of creating a pom.xml file. Maven uses pom.xml to download the required dependencies.

With this, we are ready with all the settings. Next, we can click on the Generate button, which will generate all the necessary files for bootstrapping the Spring Boot project. The browser will automatically download a ZIP file.

Once the ZIP file is downloaded, unzip the project. Open the project from the IDE. You can see a project structure similar to:

project folder structure

We can see that the dependencies we added are present in the pom.xml as artifactId:

<?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">
    
      ...
    <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>

    ...

    </dependencies>
      ...

</project>

Refer to github for complete code.

It is time to create the content in the src/main/java folder.

MongoDB Model Implementation

Our model here is the POJO or the GroceryItem class.

Let’s create a package named com.example.mdbspringboot.model and add the class GroceryItem.java.

We use the annotation @Document to set the collection name that will be used by the model. If the collection doesn’t exist, MongoDB will create it.

@Document("groceryitems")
public class GroceryItem {

        @Id
        private String id;

        private String name;
        private int quantity;
        private String category;
        
        public GroceryItem(String id, String name, int quantity, String category) {
            super();
            this.id = id;
            this.name = name;
            this.quantity = quantity;
            this.category = category;
        }
}

Using the Eclipse Source -> Generate Getters and Setters option, we can create getters and setters for this code. Specify the MongoDB document’s primary key _id using the @Id annotation. If we don’t specify anything, MongoDB will generate an _id field while creating the document.

Spring Boot MongoDB API Implementation

The API implementation happens in the repository. It acts as a link between the model and the database, and has all the methods for CRUD operations.

Let’s create a package called com.example.mdbspringboot.repository to store all the repository files.

We first create an ItemRepository public interface which extends the MongoRepository interface.


public interface ItemRepository extends MongoRepository<GroceryItem, String> {
    
    @Query("{name:'?0'}")
    GroceryItem findItemByName(String name);
    
    @Query(value="{category:'?0'}", fields="{'name' : 1, 'quantity' : 1}")
    List<GroceryItem> findAll(String category);
    
    public long count();

}

The first method, findItemByName, requires a parameter for the query, i.e., the field to filter the query by. We specify this with the annotation @Query. The second method uses the category field to get all the items of a particular category. We only want to project the field’s name and quantity in the query response, so we set those fields to 1. We reuse the method count() as it is.

MongoDB and Spring Boot CRUD Examples

Now, we are ready to create our Spring Application and run the methods to see what happens.

To connect to MongoDB Atlas, we specify the connection string in the application.properties file in the src/main/resources folder. The connection string for a cluster can be found in the Atlas UI. There is no need to write connection-related code in any other file. Spring Boot takes care of the database connection for us.

spring.data.mongodb.uri=mongodb+srv://<username>:<pwd>@<cluster>.mongodb.net/mygrocerylist
spring.data.mongodb.database=mygrocerylist

We are also specifying the database name here — if it doesn’t exist, MongoDB will create one.

In this Spring Boot MongoDB example, we are not using the Controller and the View. We will use a CommandLineRunner to view the output on the console.

Create the main class MdbSpringBootApplication.java in the root package com.example.mdbspringboot:

@SpringBootApplication
@EnableMongoRepositories
public class MdbSpringBootApplication implements CommandLineRunner{
    
    @Autowired
    ItemRepository groceryItemRepo;
    
    public static void main(String[] args) {
        SpringApplication.run(MdbSpringBootApplication.class, args);
    }

Our class MdbSpringBootApplication implements the CommandLineRunner interface to run the spring application. ItemRepository is Autowired, allowing Spring to find it automatically. Spring initializes the Application Context using the @SpringBootApplication annotation. We also activate the Mongo Repositories using @EnableMongoRepositories. Our project structure should be similar to the below structure now:

Let’s now add the repository methods to the main class for CRUD operations:

Create operation using Spring Boot MongoDB

In order to create new documents, we will use the save method. The save method is available to us through the SimpleMongoRepository class, which implements the MongoRepository interface. Our ItemRepository interface extends MongoRepository.

The save method will take a GroceryItem object as a parameter. Here, we will create five grocery items (documents) and save them into MongoDB using the save method.

//CREATE
    void createGroceryItems() {
        System.out.println("Data creation started...");
        groceryItemRepo.save(new GroceryItem("Whole Wheat Biscuit", "Whole Wheat Biscuit", 5, "snacks"));
        groceryItemRepo.save(new GroceryItem("Kodo Millet", "XYZ Kodo Millet healthy", 2, "millets"));
        groceryItemRepo.save(new GroceryItem("Dried Red Chilli", "Dried Whole Red Chilli", 2, "spices"));
        groceryItemRepo.save(new GroceryItem("Pearl Millet", "Healthy Pearl Millet", 1, "millets"));
        groceryItemRepo.save(new GroceryItem("Cheese Crackers", "Bonny Cheese Crackers Plain", 6, "snacks"));
        System.out.println("Data creation complete...");
    }

Read operations using Spring Boot MongoDB

In this application, we are performing four different read operations:

  • Fetch all the documents (grocery items) using the findAll() method.
  • Get a single item (document) by its name field using the findItemByName method.
  • Get a list of items based on a category.
  • Get the count of items.
// READ
    // 1. Show all the data
     public void showAllGroceryItems() {
         
         groceryItemRepo.findAll().forEach(item -> System.out.println(getItemDetails(item)));
     }
     
     // 2. Get item by name
     public void getGroceryItemByName(String name) {
         System.out.println("Getting item by name: " + name);
         GroceryItem item = groceryItemRepo.findItemByName(name);
         System.out.println(getItemDetails(item));
     }
     
     // 3. Get name and quantity of a all items of a particular category
     public void getItemsByCategory(String category) {
         System.out.println("Getting items for the category " + category);
         List<GroceryItem> list = groceryItemRepo.findAll(category);
         
         list.forEach(item -> System.out.println("Name: " + item.getName() + ", Quantity: " + item.getQuantity()));
     }
     
     // 4. Get count of documents in the collection
     public void findCountOfGroceryItems() {
         long count = groceryItemRepo.count();
         System.out.println("Number of documents in the collection: " + count);
     }

We can create a helper method to display the output of read operations in a readable format:

 // Print details in readable form
     
     public String getItemDetails(GroceryItem item) {

         System.out.println(
         "Item Name: " + item.getName() + 
         ", \nQuantity: " + item.getQuantity() +
         ", \nItem Category: " + item.getCategory()
         );
         
         return "";
     }

Update operation using Spring Boot MongoDB

Suppose we change our mind and like the word “munchies” better in place of “snacks” for our grocery list. We would need to change all the documents where the category is “snacks.” To do that, we have to first fetch all the documents of the category “snacks,” set the category to “munchies,” and then save all the documents.

 public void updateCategoryName(String category) {
         
         // Change to this new value
         String newCategory = "munchies";
         
         // Find all the items with the category snacks
         List<GroceryItem> list = groceryItemRepo.findAll(category);
         
         list.forEach(item -> {
             // Update the category in each document
             item.setCategory(newCategory);
         });
         
         // Save all the items in database
         List<GroceryItem> itemsUpdated = groceryItemRepo.saveAll(list);
         
         if(itemsUpdated != null)
             System.out.println("Successfully updated " + itemsUpdated.size() + " items.");         
     }

Delete operation using Spring Boot MongoDB

If, instead of updating an item or category, we want to delete a grocery item off of our list, we can. We can delete the grocery item with a particular ID using the pre-defined deleteById method.

// DELETE
     public void deleteGroceryItem(String id) {
         groceryItemRepo.deleteById(id);
         System.out.println("Item with id " + id + " deleted...");
     }

To delete all the items, we can use the groceryItemRepo.deleteAll(); method. Deleting all the documents will not delete the collection.

Putting the CRUD operations together

Next, we implement the CommandLineRunner.run() method to call the above methods:

public void run(String... args) {
        
        System.out.println("-------------CREATE GROCERY ITEMS-------------------------------\n");
        
        createGroceryItems();
        
        System.out.println("\n----------------SHOW ALL GROCERY ITEMS---------------------------\n");
        
        showAllGroceryItems();
        
        System.out.println("\n--------------GET ITEM BY NAME-----------------------------------\n");
        
        getGroceryItemByName("Whole Wheat Biscuit");
        
        System.out.println("\n-----------GET ITEMS BY CATEGORY---------------------------------\n");
        
        getItemsByCategory("millets");
    
          System.out.println("\n-----------UPDATE CATEGORY NAME OF SNACKS CATEGORY----------------\n");
        
        updateCategoryName("snacks");    
                
        System.out.println("\n----------DELETE A GROCERY ITEM----------------------------------\n");
        
        deleteGroceryItem("Kodo Millet");
        
        System.out.println("\n------------FINAL COUNT OF GROCERY ITEMS-------------------------\n");
        
        findCountOfGroceryItems();
        
        System.out.println("\n-------------------THANK YOU---------------------------");
        
    }

The system.out statements are only for beautification of the output.

Here is the expected output when we run the program:

-------------CREATE GROCERY ITEMS-------------------------------

Data creation started...
Data creation complete...

----------------SHOW ALL GROCERY ITEMS---------------------------

Item Name: Whole Wheat Biscuit, 
Item Quantity: 5, 
Item Category: snacks

Item Name: XYZ Kodo Millet healthy, 
Item Quantity: 2, 
Item Category: millets

Item Name: Dried Whole Red Chilli, 
Item Quantity: 2, 
Item Category: spices

Item Name: Healthy Pearl Millet, 
Item Quantity: 1, 
Item Category: millets

Item Name: Bonny Cheese Crackers Plain, 
Item Quantity: 6, 
Item Category: snacks


--------------GET ITEM BY NAME-----------------------------------

Getting item by name: Whole Wheat Biscuit
Item Name: Whole Wheat Biscuit, 
Item Quantity: 5, 
Item Category: snacks


-----------GET ITEMS BY CATEGORY---------------------------------

Getting items for the category millets
Name: XYZ Kodo Millet healthy, Quantity: 2
Name: Healthy Pearl Millet, Quantity: 1

-----------UPDATE CATEGORY NAME OF SNACKS CATEGORY----------------

Successfully updated 2 items.

----------DELETE A GROCERY ITEM----------------------------------

Item with id Kodo Millet deleted...

------------FINAL COUNT OF GROCERY ITEMS-------------------------

Number of documents in the collection = 4

-------------------THANK YOU---------------------------

Update operation with Spring Boot MongoDB using MongoTemplate

To perform update operations using a particular field, we can also use the MongoTemplate class. It provides out-of-the-box functionalities present in the org.springframework.data.mongodb.core.query package. We don’t need to write many lines of code and the update can be done in a single database interaction. We can use MongoTemplate for more complex operations like aggregations, as well (not in scope for this tutorial).

To use the MongoTemplate class for the update, we should create a custom repository where we build the update query.

Let’s write a method to update the quantity of a grocery item.

Create an interface CustomItemRepository:

public interface CustomItemRepository {
    
    void updateItemQuantity(String name, float newQuantity);

}

We can add as many methods as we need in the interface and provide the implementations in the CustomItemRepositoryImpl class:

@Component
public class CustomItemRepositoryImpl implements CustomItemRepository {

    @Autowired
    MongoTemplate mongoTemplate;
    
    public void updateItemQuantity(String name, float newQuantity) {
        Query query = new Query(Criteria.where("name").is(name));
        Update update = new Update();
        update.set("quantity", newQuantity);
        
        UpdateResult result = mongoTemplate.updateFirst(query, update, GroceryItem.class);
        
        if(result == null)
            System.out.println("No documents updated");
        else
            System.out.println(result.getModifiedCount() + " document(s) updated..");

    }

}

Since MongoTemplate is @Autowired, Spring will inject the object dependency. In addition, @Component annotation will allow Spring itself to detect the CustomItemRepository interface.

The next step is to call this method from our main class. Similar to how we declared the groceryItemRepo, we should declare our customRepo:

    @Autowired
    CustomItemRepository customRepo;

Next, write the method in the main class that calls our customRepo method:

// UPDATE
     public void updateItemQuantity(String name, float newQuantity) {
         System.out.println("Updating quantity for " + name);
         customRepo.updateItemQuantity(name, newQuantity);
     }

Add the above method in the run method to call it when the application is executed:

System.out.println("\n-----------UPDATE QUANTITY OF A GROCERY ITEM------------------------\n");
        
        updateItemQuantity("Bonny Cheese Crackers Plain", 10);

You should get the result as:

-----------UPDATE QUANTITY OF A GROCERY ITEM------------------------

Updating quantity for Bonny Cheese Crackers Plain
1 document(s) updated..

Like we mentioned earlier, we were able to do the update in a single database transaction as compared to with MongoRepository, where we had to do three operations, i.e., find, set, and then save. MongoTemplate also provides the updateMulti() method, to update multiple documents in a single go.

It’s Easy to Connect MongoDB Atlas with Spring Boot

Through this article, we demonstrated that MongoDB Spring Boot integration is easy using:

  • Starter data MongoDB artifactid (the dependency we added while creating the Spring Initializr project) in pom.xml
  • A property on application.properties file to specify the connection string to a MongoDB cluster

Connection to MongoDB Atlas does not require any other code. MongoDB Atlas is a convenient way to store and access data anywhere. Visit the MongoDB Atlas page to get started, if you would like to work along with this tutorial yourself. If you have already worked along with us in this simple tutorial and understand how to use Spring Boot with MongoDB, read REST APIs with Java, Spring Boot, and MongoDB to learn how to perform advanced operations and appreciate the full benefits of using a Spring Boot application by using the business (controller) and presentation (view) layers as well. Additionally, you can check out the full MongoDB University course on MongoDB for Java Developers.

Try this tutorial for yourself.

FAQ

How does MongoDB connect to Spring Boot?

MongoDB can connect to Spring Boot in two ways — the MongoRepository interface and the MongoTemplate class. MongoRepository extends the CrudRepository interface that contains methods to perform basic CRUD operations. For writing custom queries and aggregations, and for a finer control over query filters, we can use the MongoTemplate class. MongoTemplate class implements interfaces that support operations like aggregation, find, update, upsert, index, remove, and more.

Which database is best for Spring Boot?

Both SQL and NoSQL databases are well suited for Spring Boot. However, a NoSQL database like MongoDB offers several benefits due to its embedded document-based structure. Document structure is a more natural way to describe and traverse through data. Data that is viewed together stays together. Spring also provides connectors like MongoTemplate and MongoRepository to perform all the database operations in MongoDB.

What is Spring Boot used for?

Spring Boot framework is used to create production-ready web applications with default configurations. Developers need not write extensive code. Spring Boot significantly reduces the development time. It automatically adds commonly used libraries for web applications, such as:

  • spring-webmvc
  • tomcat
  • validation-api

for easier dependency management.

Spring Boot also has embedded servlet container support. We can run Java programs as a standalone application by adding the spring-boot-starter-web dependency in pom.xml.

What is a Spring Boot with MongoDB CRUD example?

A common Spring Boot with MongoDB CRUD example could be a grocery shopping list of a user. A user may want to

  • add (create) items to their grocery list; for example, add milk,
  • delete items from the grocery list; for example, delete eggs since they were added by mistake,
  • update items on the list; for example, buy four packets of milk instead of two

The CRUD operations are done using MongoRepository and MongoTemplate. We can use both by adding the spring-boot-starter-data-mongodb dependency in pom.xml.