Integrating MongoDB with Spring Boot for Data Persistence

Project Dependencies

To begin, configure the pom.xml file with the necessary dependencies for Spring Boot, MongoDB integration, and Lombok to reduce boilerplate code.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>

    <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>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Database Configuration

Configure the MongoDB connection settings in the application.yml file. This example connects to a local instance on the default port.

server:
  port: 8080

spring:
  application:
    name: mongo-demo-service
  data:
    mongodb:
      host: 127.0.0.1
      database: user_db

Application Entry Point

The standard Spring Boot main class to bootstrap the application.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

Data Model

Define the entity class UserProfile. This class represents a document in the MongoDB collection. Lombok annotations are used to generate getters and setters.

package com.example.demo.model;

import lombok.Data;
import org.springframework.data.annotation.Id;

@Data
public class UserProfile {
    @Id
    private String id;
    private String username;
    private Integer age;
}

Repository Layer

Create the repository interface by extending MongoRepository. A custom query method is defined to search for users by name pattern and age range with pagination support.

package com.example.demo.repository;

import com.example.demo.model.UserProfile;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository<UserProfile, String> {
    Page<UserProfile> findByUsernameContainingAndAgeBetween(String name, Integer minAge, Integer maxAge, Pageable pageable);
}

Service Layer

The service layer handles business logic. It utilizes both MongoRepository for standard CRUD and MongoTemplate for more complex operations, such as atomic field increments.

package com.example.demo.service;

import com.example.demo.model.UserProfile;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    public Page<UserProfile> searchUsers(String name, Integer min, Integer max, Pageable pageable) {
        return userRepository.findByUsernameContainingAndAgeBetween(name, min, max, pageable);
    }

    public UserProfile getUserById(String id) {
        return userRepository.findById(id).orElse(null);
    }

    public void createUser(UserProfile user) {
        userRepository.save(user);
    }

    public void updateUser(UserProfile user) {
        userRepository.save(user);
    }

    public void incrementUserAge(String userId) {
        Query searchQuery = new Query(Criteria.where("id").is(userId));
        Update modification = new Update().inc("age", 1);
        mongoTemplate.updateFirst(searchQuery, modification, UserProfile.class);
    }

    public void deleteUser(String id) {
        userRepository.deleteById(id);
    }
}

Controller Layer

The REST controller exposes endpoints for client interaction. It uses a generic wrapper class ApiResponse for consistent JSON responses.

package com.example.demo.controller;

import com.example.demo.model.UserProfile;
import com.example.demo.service.UserService;
import com.example.demo.util.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/api/users")
@CrossOrigin
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/search")
    public ApiResponse search(@RequestBody Map<String, Object> payload) {
        int pageNum = (Integer) payload.getOrDefault("pageNum", 1);
        int pageSize = (Integer) payload.getOrDefault("pageSize", 10);
        PageRequest pageRequest = PageRequest.of(pageNum - 1, pageSize);

        String name = (String) payload.getOrDefault("username", "");
        Integer minAge = (Integer) payload.getOrDefault("minAge", 0);
        Integer maxAge = (Integer) payload.getOrDefault("maxAge", 120);

        Page<UserProfile> result = userService.searchUsers(name, minAge, maxAge, pageRequest);
        return ApiResponse.success(result);
    }

    @GetMapping("/{id}")
    public ApiResponse getById(@PathVariable String id) {
        return ApiResponse.success(userService.getUserById(id));
    }

    @PostMapping("/save")
    public ApiResponse save(@RequestBody UserProfile user) {
        user.setId(UUID.randomUUID().toString());
        userService.createUser(user);
        return ApiResponse.success("User created successfully");
    }

    @PostMapping("/update")
    public ApiResponse update(@RequestBody UserProfile user) {
        userService.updateUser(user);
        return ApiResponse.success("User updated successfully");
    }

    @PostMapping("/incrementAge/{id}")
    public ApiResponse incrementAge(@PathVariable String id) {
        userService.incrementUserAge(id);
        return ApiResponse.success("Age updated successfully");
    }

    @DeleteMapping("/delete/{id}")
    public ApiResponse delete(@PathVariable String id) {
        userService.deleteUser(id);
        return ApiResponse.success("User deleted successfully");
    }
}

Response Wrapper Utility

A utility class to standardize the API response structure, including status codes, messages, and data payload.

package com.example.demo.util;

import java.util.HashMap;
import java.util.Map;

public class ApiResponse {
    private int code;
    private String message;
    private Map<String, Object> data = new HashMap<>();

    public static ApiResponse success() {
        ApiResponse response = new ApiResponse();
        response.code = 200;
        response.message = "Success";
        return response;
    }

    public static ApiResponse success(Object payload) {
        ApiResponse response = success();
        response.data.put("result", payload);
        return response;
    }

    public static ApiResponse fail() {
        ApiResponse response = new ApiResponse();
        response.code = 400;
        response.message = "Error";
        return response;
    }

    // Getters and Setters
    public int getCode() { return code; }
    public void setCode(int code) { this.code = code; }
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
    public Map<String, Object> getData() { return data; }
    public void setData(Map<String, Object> data) { this.data = data; }
}

Tags: spring-boot mongodb spring-data-mongodb java rest-api

Posted on Mon, 22 Jun 2026 18:02:18 +0000 by cheald