Configuring Spring Boot for MongoDB

Configuring Spring Boot for MongoDB

16 Comments

Last Updated on June 5, 2019 by Michelle Mesiona

Spring Data project provides integration for most of the popular databases around. I have already written few posts to configure Spring Boot to use Oracle, MySQL, and PostgreSQL – all RDBMS widely used in the enterprise.

Recently, we’ve seen a rise in popularity of NoSQL databases. MongoDB has rapidly gained popularity in the enterprise and the Spring community.

In this post, I’ll discuss how to use MongoDB with a Spring Boot application.

NoSQL and MongoDB

NoSQL storage is a vast domain with a plethora of solutions and patterns. Even the term NoSQL have multiple meanings. Originally, it stood for “Non SQL”, but gradually with the adoption of Polyglot Persistence which Martin Flower beautifully describes here, NoSQL is now commonly referred as “Not Only SQL”.

MongoDB is a leading document-based NoSQL database. MongoDB uses JSON documents to store records. Internally, MongoDB represents JSON documents in binary-encoded format called BSON. One feature worth mentioning about MongoDB is its dynamic schema. You can insert data without a pre-defined schema – a thing not possible with traditional relational databases.

In today’s competitive business environment where Agile practices are embraced, having a dynamic schema gives you a high degree of flexibility. A great place to learn more about MongoDB is here.

For this post, I’m using MongoDB installed locally on my laptop.

You have several options for running MongoDB. Refer to the MongoDB guide for an explanation on how to install and start up a MongoDB instance.

Spring Framework 5
Checkout my Spring Framework 5: Beginner to Guru online course!

MongoDB Dependencies

Spring Data for MongoDB is part of the umbrella Spring Data project. With Spring Data for MongoDB, you get a familiar and consistent Spring-based programming model to work with MongoDB while retaining MongoDB store-specific features and capabilities.

To use MongoDB in a Spring Boot project, we need to add the Spring Data MongoDB starter dependency, spring-boot-starter-data-mongodb . The Maven POM is this.

pom.xml

   //

	4.0.0
	guru.springframework
	blogposts
	0.0.1-SNAPSHOT
	jar
	Blog Posts
	Misc Blog Posts
	
		org.springframework.boot
		spring-boot-starter-parent
		1.4.4.RELEASE
		 
	
	
		UTF-8
		guru.springframework.blog.BlogPostsApplication
		1.8
	
	
		
			org.springframework.boot
			spring-boot-starter
		

		
			org.springframework.boot
			spring-boot-starter-data-mongodb
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
	
	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
		
	

Notice that we haven’t included Spring Data JPA. The Spring Data MongoDB starter dependency brings in the required infrastructure, the MongoDB driver, and few other dependencies to the project.

MongoDB Dependencies with Spring Boot starter

Data Class

Both Spring Data JPA and Spring Data MongoDB share a common infrastructure. I have already written a post to use Spring Data JPA in a Spring Boot Web application.

Here we need to write a Mongo data class rather than a JPA @Entity. A Mongo data class instance maps to a document stored in a collection.

Note: You can relate a collection of MongoDB to an RDBMS table, and a document to a table row.

Let’s write a User data class.

User.java

   //package guru.springframework.blog.domain;

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

@Document(collection = "users")
public class User {
    @Id
    private String id;
    private String name;
    private int age;
    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                ", name='" + name + '\'' +
                ", Age=" + age +
                '}';
    }
}

We have created User as a plain Java object. The @Document annotation in Line 6 specifies a users collection. This tells Spring Data MongoDB to store a User document to the users collection. This collection will be created if it doesn’t exist. The @Document annotation is optional, and if we don’t use one, the collection will be named with the class name.

All documents in MongoDB have an _id field as the primary key. The id field annotated with @Id in Line 8 maps to the MongoDB document’s _id. It’s not mandatory to use the @Id annotation if the primary key field is named id . However, many developers still use the annotation for readability. Some consider it a best practice to use the Id annotation, even when its not required.

The remaining name and age field will be treated as properties of the MongoDB document.

Mongo Repository

Spring Data Mongo provides Mongo Repository, similar to CRUD Repository of Spring Data JPA. In fact, the MongoRepository interface extends CrudRepository to manage data objects for most common operations, such as saving a document, updating it, deleting it, or finding it by id.

You only need to define the repository interface. Spring Data MongoDB will automatically provide the required implementations.

Here is the Mongo repository:

UserMongoRepository.java

   //package guru.springframework.blog.repositories;

import guru.springframework.blog.domain.User;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserMongoRepository extends MongoRepository {
    User findByName(String name);
}

That’s all we need to set to use MongoDB with Spring Boot.

Unit Testing

Let’s write some test code for our setup.

UserMongoRepositoryTest.java

   //package guru.springframework.blog.repositories;

import guru.springframework.blog.domain.User;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMongoRepositoryTest {
    @Autowired
    private UserMongoRepository userMongoRepository;


    @Before
    public void setUp() throws Exception {
        User user1= new User("Alice", 23);
        User user2= new User("Bob", 38);
        //save product, verify has ID value after save
        assertNull(user1.getId());
        assertNull(user2.getId());//null before save
        this.userMongoRepository.save(user1);
        this.userMongoRepository.save(user2);
        assertNotNull(user1.getId());
        assertNotNull(user2.getId());
    }

    @Test
    public void testFetchData(){
        /*Test data retrieval*/
        User userA = userMongoRepository.findByName("Bob");
        assertNotNull(userA);
        assertEquals(38, userA.getAge());
        /*Get all products, list should only have two*/
        Iterable users = userMongoRepository.findAll();
        int count = 0;
        for(User p : users){
            count++;
        }
        assertEquals(count, 2);
    }

    @Test
    public void testDataUpdate(){
        /*Test update*/
        User userB = userMongoRepository.findByName("Bob");
        userB.setAge(40);
        userMongoRepository.save(userB);
        User userC= userMongoRepository.findByName("Bob");
        assertNotNull(userC);
        assertEquals(40, userC.getAge());
    }

    @After
    public void tearDown() throws Exception {
      this.userMongoRepository.deleteAll();
    }

}

For the test, I have used JUnit. To learn more about JUnit, refer my series on JUnit Testing.

Here is the result of the JUnit test.
JUnit Test Result for MongoDB

Configuration Properties

If you are wondering about MongoDB configurations for this simple application, we relied on the defaults. Spring Data MongoDB intelligently picks up the defaults, such as localhost for the host, 27017 for the default MongoDB port, and test for the default MongoDB database to connect. For other values or for advance configurations, you can use the application.properties or application.yml configuration files.

The MongoDB configurations that Spring Boot supports are as follows:

spring.data.mongodb.authentication-database= # Authentication database name.
spring.data.mongodb.database=test # Database name.
spring.data.mongodb.field-naming-strategy= # Fully qualified name of the FieldNamingStrategy to use.
spring.data.mongodb.grid-fs-database= # GridFS database name.
spring.data.mongodb.host=localhost # Mongo server host.
spring.data.mongodb.password= # Login password of the mongo server.
spring.data.mongodb.port=27017 # Mongo server port.
spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories.
spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. When set, host and port are ignored.
spring.data.mongodb.username= # Login user of the mongo server.

Conclusion

Spring Boot makes it very easy to get a Spring application talking to a Mongo database. By default, Spring Boot is configured to look for the Mongo database on the local host. When you’re ready to deploy, you just need to override a handful of default properties for your particular MongoDB installation.

Spring Framework 5
Click here to learn more about my Spring Framework 5: Beginner to Guru online course!

About jt

    You May Also Like

    16 comments on “Configuring Spring Boot for MongoDB

    1. June 29, 2017 at 3:15 am

      i don’t understand anything! :(((

      Reply
    2. March 9, 2018 at 6:22 am

      Hi, great post. Do you know if is there some conf attribute like ‘validation-query: SELECT 1’ on order to to keep the connection alive? or set socketKeepAlive to true is enpugh?

      Reply
      • March 9, 2018 at 7:25 am

        Thanks – Sorry, I don’t know.

        Reply
    3. March 15, 2018 at 8:30 am

      hi i am facing error “Cannot determine embedded database driver class for database type NONE”
      while i run mongoDB project

      Reply
      • March 15, 2018 at 1:52 pm

        Check your embedded MongoDB dependency in pom.xml

        Reply
    4. March 16, 2018 at 1:29 pm

      I think you need to add @EnableMongoRepositories annotation in Application

      Reply
    5. May 1, 2018 at 5:43 pm

      How to access embedded MongoDB in console?

      Reply
    6. June 12, 2018 at 6:34 pm

      Based on your expertise, do you think would be a bad practice o risky to deploy a spring boot application with an embedded mongodb in production? The application would be using the embedded mongodb to store no more that 7,000 records in memory which would be loaded when the application is started up. The general idea is to use the embedded mongodb as cache.

      Reply
      • June 12, 2018 at 6:57 pm

        For just 7,000 records loaded on startup, I’d prob just use a HashMap.

        Reply
        • June 12, 2018 at 7:18 pm

          Thank you for your quick response. I forgot to mention that I’m taking advantage of spring data features in order to perform search criteria query’s and updates over the data. The updates on memory happen on demand after updates on a relational dB and no more than 200 records are updated per day. What would be your advices after these facts? Thank you

          Reply
    7. June 13, 2018 at 6:01 am

      Same – you’re not dealing with much data.

      Reply
      • June 13, 2018 at 6:13 am

        thank you for your advice

        Reply
    8. May 20, 2019 at 10:47 am

      The source code is not available anymore on this page. I cannot access your JPA project too.

      Reply
      • May 23, 2019 at 11:54 am

        Fixed now – in the process of making some updates to the site.

        Reply
    9. September 28, 2019 at 1:17 pm

      How can I start my mongoDB in docker when I start SpringBoot app?
      I do not want to manually start Mongo, but some scripting or other technique to run localhost mongo docker.

      Reply

    Leave a Reply

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

    This site uses Akismet to reduce spam. Learn how your comment data is processed.