Getting Started with Spring Data MongoDB using Java Configuration

In this tutorial I’ll show you how to use Spring Data MongoDB to integrate a MongoDB NoSQL database into a Spring Boot application.

I’ll use these technologies and tools:

  • Spring Tool Suite (STS) 3.8.4.RELEASE
  • Java 8
  • Spring Boot 1.5.3.RELEASE
  • Maven 3.3.9
  • MongoDB 3.3.4

1. The Project Structure

The final folder structure of our project.

The project structure of our Spring Data MongoDB Project as seen in STS

2. Create a new Spring Boot project

If you’re using STS, you can easily create a starter project by either selecting File > New > Spring Starter Project from the main menu or right-click on the Package Explorer and select New > Spring Starter Project.

STS command to create a new Spring Starter Project

STS dialog window for Spring Starter Project

STS dialog window for Spring Boot Starter with Data MongoDB

In case you’re using another IDE like Eclipse, Netbeans or IntelliJ IDEA, you can create a new Maven project and add to the pom.xml file the dependencies listed in the next paragraph.

3. Maven Dependencies

spring-boot-starter-data-mongodb is the fundamental dependency for our project.

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.thomasvitale</groupId>
  <artifactId>Application</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Application</name>
  <description>Demo application for Spring Data MongoDB</description>

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
  </properties>

  <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-test</artifactId>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

4. Spring Configuration using Java Annotations

Spring lets you use either Java configuration or XML configuration or a mix of the two. I’ll use a pure Java configuration. MongoDB properties are stored in a dedicated file.

package com.thomasvitale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import com.mongodb.Mongo;
import com.mongodb.MongoClient;

@Configuration
@EnableMongoRepositories(basePackages = "com.thomasvitale.repository")
@PropertySource("classpath:mongo.properties")
public class MongoConfig extends AbstractMongoConfiguration {
  
  @Autowired
  private Environment env;

  @Override
  protected String getDatabaseName() {
    return env.getProperty("mongo.database");
  }

  @Override
  public Mongo mongo() throws Exception {
    return new MongoClient(env.getProperty("mongo.host"), Integer.parseInt(env.getProperty("mongo.port")));
  }
  
  @Override
  protected String getMappingBasePackage() {
    return "com.thomasvitale.model";
  }

}
mongo.database=mydb
mongo.host=127.0.0.1
mongo.port=32769

5. Person Model

This is the Person Model. The @Document(collection = "persons") annotation specifies in which collection to save a Person document.

package com.thomasvitale.model;

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

@Document(collection = "persons")
public class Person {

  @Id
  private String id;

  private String firstName;
  private String lastName;
  
  public Person() {
  }
  
  public Person(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  public String getId() {
    return id;
  }

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

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  
  @Override
  public String toString() {
    return firstName + " " + lastName;
  }

}

6. Person Repository

By extending MongoRepository, our PersonRepository has a lot of available operations, including the standard CRUD operations. You can also add custom operations like findByFirstName and findByLastName without writing any implementation: Spring Data MongoDB creates them for you!

package com.thomasvitale.repository;

import java.util.List;

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

import com.thomasvitale.model.Person;

public interface PersonRepository extends MongoRepository<Person, String> {
  
  public Person findByFirstName(String firstName);
  public List<Person> findByLastName(String lastName);
  
}

7. Demo

Since we have Spring Data MongoDB configured, a model and a repository, it’s time to test the application by performing some CRUD and custom operations.

package com.thomasvitale;

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

import com.thomasvitale.model.Person;
import com.thomasvitale.repository.PersonRepository;

@SpringBootApplication
public class Application implements CommandLineRunner {
  
  @Autowired
  PersonRepository personRepository;

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

  @Override
  public void run(String... arg0) throws Exception {
    
    // Save two Person documents on Mongo
    personRepository.save(new Person("Sheldon", "Cooper"));
    personRepository.save(new Person("Missy", "Cooper"));
    personRepository.save(new Person("Leonard", "Hofstadter"));
    
    // Get all people
    System.out.println(">>> All people in the database:");
    personRepository.findAll().forEach(System.out::println);

    // Get all people with a specific last name
    System.out.println(">>> All people with last name = 'Cooper'");
    personRepository.findByLastName("Cooper").forEach(System.out::println);
    
    // Update an individual person
    Person person = personRepository.findByFirstName("Sheldon");
    person.setFirstName("Shelly");
    personRepository.save(person);

    // Delete all 
    personRepository.deleteAll();
  }
}

Resources

Leave a Reply

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