Spring Boot with MongoDB

In this tutorial, you will learn how to build a Spring Boot application, connect it with a MongoDB database, and create REST APIs for inserting, reading, updating, and deleting data from the MongoDB database.


Follow these steps to complete this tutorial:

  1. Go to the Spring Initializr website at https://start.spring.io.
  2. Set up the project configuration:
    • Choose the project type (Maven or Gradle).
    • Set the language to Java.
    • Specify the Spring Boot version.
    • Enter a Group and Artifact name for your project. The group name is the id of the project. Artifact is the name of your project.
    • Add any necessary project metadata (description, package name, etc.).
    • Choose between packaging as a JAR (Java Archive) or a WAR (Web Application Archive) depends on how you plan to deploy your Spring Boot application. Choose JAR packaging if you want a standalone executable JAR file and WAR packaging if you intend to deploy your application to a Java EE application server or servlet container. When you package your Spring Boot application as a JAR using JAR packaging, it includes an embedded web server, such as Tomcat, by default. This means that you don't need to separately deploy your application to an external Tomcat server. Instead, you can run the JAR file directly, and the embedded Tomcat server will start and serve your application.
    • Select the Java version based on the compatibility requirements of your project. Consider the specific needs of your project, any compatibility requirements, and the Java version supported by your target deployment environment when making these choices.
  3. Add project dependencies:
    • Click on the "Add Dependencies" button.
    • Select the dependencies that your project requires (Spring Web, Spring Boot DevTools, Spring Data MongoDB, and Lombok). Spring Data MongoDB provides integration with MongoDB for easy data access.

    Refer to this image for example:



  4. Generate the project:
    • Click on the "Generate" button.
    • Spring Initializr will generate a zip file containing your Spring Boot project.
  5. Download and extract the generated project:
    • Download the zip file generated by Spring Initializr.
    • Extract the contents of the zip file to a directory on your local machine.
  6. Import the project into your IDE:
    • Open your preferred IDE (IntelliJ IDEA, Eclipse, or Spring Tool Suite).
    • Import the extracted project as a Maven or Gradle project, depending on the build system you chose in Spring Initializr.
  7. Add Configurations:
  8. Open the src/main/resources/application.properties file in your Eclipse editor and add the following configuration lines to the file:

    server.port = 8080
    
    # MongoDB Configuration
    spring.data.mongodb.host = localhost
    spring.data.mongodb.port = 27017
    spring.data.mongodb.database = database_name
    spring.data.mongodb.username = myusername
    spring.data.mongodb.password = password123

    Here, server.port=8080 configuration line is used to specify the port number on which the server will listen for incoming requests. In this case, it sets the server port to 8080.

    spring.data.mongodb.host: Specifies the MongoDB server's hostname or IP address. In this case, it's set to localhost, indicating that the MongoDB server is running on the same machine as the Spring Boot application.

    spring.data.mongodb.port: Specifies the MongoDB server's port number. In this case, it's set to 27017, which is the default port for MongoDB.

    spring.data.mongodb.database: Specifies the name of the MongoDB database to be used. In this case, it's set to database_name.

    spring.data.mongodb.username and spring.data.mongodb.password: These properties define the username and password for authenticating the MongoDB connection. In this case, the username is set to myusername, and the password is set to password123.


  9. Implement your business logic by creating controllers, services, repositories, and other necessary components:
  10. Create a Student class that represents the student entity. This class can have properties such as id, firstName, lastName, email, etc., along with their getters and setters methods:

    package com.example.student.entity;
    
    import java.util.Date;
    import org.springframework.data.annotation.CreatedDate;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.annotation.LastModifiedDate;
    import org.springframework.data.mongodb.core.mapping.Document;
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Builder
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Document(collection = "student")
    public class Student {
    	@Id
    	private String id;
    	private String firstName;
    	private String lastName;
    	private String email;
    	private String mobileNumber;
    	private Date dateOfBirth;
    	private String createdBy;
    	private String modifiedBy;
    	@CreatedDate
    	private Date created;
    	@LastModifiedDate
    	private Date modified;
    
    }
    

    Create a StudentRepository interface that represents a repository responsible for handling data access operations related to students:

    package com.example.student.repository;
    
    
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.repository.CrudRepository;
    import org.springframework.stereotype.Repository;
    import com.example.student.entity.Student;
    
    @Repository
    public interface StudentRepository extends CrudRepository<Student, String> {
    
    	public Page<Student> findAll(Pageable pageable);
    		
    }


    Create a StudentRequest class as a Data Transfer Object (DTO) to represent the request payload for creating a student:

    package com.example.student.model;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class StudentRequest {
    
      private String studentId;
      private String firstName;
      private String lastName;
      private String email;
      private String mobileNumber;
      private String dateOfBirth;
    
    }

    StudentRequest should have properties such as firstName, lastName, email, etc., which correspond to the data you need to provide when creating a student. You can add more properties to the class as needed based on your specific requirements.


    Create a StudentResponse class as a Data Transfer Object (DTO) to represent the response for retrieving student information:

    package com.example.student.model;
    
    import java.util.Date;
    import lombok.Builder;
    import lombok.Data;
    
    @Builder
    @Data
    public class StudentResponse {
    
       private String studentId;
       private String firstName;
       private String lastName;
       private String email;
       private String mobileNumber;
       private String dateOfBirth;
       private String createdBy;
       private String modifiedBy;
       private Date created;
       private Date modified;
    
    }

    In this example, the StudentResponse class represents the DTO for the response when retrieving student information. It includes properties such as firstName, lastName, email, studentId, etc., which correspond to the data you want to include in the response.


    Next, we will create classes to handle custom exceptions.  Custom exceptions allow you to create specific exception types for your application that can be thrown when certain exceptional situations occur.

    Let's start by creating a Java class named Error with three private fields: message, status, and timestamp. The use of Lombok @Data annotation will generate the getter and setter methods. This class represents data container that holds information related to an error:

    package com.example.exception.model;
    
    import lombok.Data;
    
    @Data
    public class Error {
       private String message;
       private int status;
       private Long timestamp;
    }

    Create a custom exception class named DataMissingException, which extends the RuntimeException class:

    package com.example.exception;
    
    public class DataMissingException extends RuntimeException {
       private static final long serialVersionUID = 1L;
    
       public DataMissingException(String message) {
          super(message);
       }
    
    }

    Extending RuntimeException indicates that DataMissingException is a subclass of the built-in RuntimeException class. It also means that our custom exception is an unchecked exception, meaning that it does not require explicit handling using try-catch blocks or declaring them in method signatures.


    Create a custom exception class named DataNotModifiedException, which extends the RuntimeException class:

    package com.example.exception;
    
    public class DataNotModifiedException extends RuntimeException {
       private static final long serialVersionUID = 1L;
    
       public DataNotModifiedException(String message) {
          super(message);
       }
    }

    Create a custom exception class named ResourceNotFoundException, which extends the RuntimeException class:

    package com.example.exception;
    
    public class ResourceNotFoundException extends RuntimeException {
       private static final long serialVersionUID = 1L;
    
       public ResourceNotFoundException(String message) {
          super(message);
       }
    }

    Create a custom exception class named InvalidDataException, which extends the RuntimeException class:

    package com.example.exception;
    
    public class InvalidDataException extends RuntimeException {
       private static final long serialVersionUID = 1L;
    
       public InvalidDataException(String message) {
          super(message);
       }
    }

    Create a Global Exception Handler class named GlobalExceptionHandlerController. The purpose of this class is to handle specific exceptions globally, providing consistent and customized error responses to clients when certain exceptions occur during the application's execution:

    package com.example.exception.controller;
    
    import java.util.Date;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import com.example.exception.DataMissingException;
    import com.example.exception.DataNotModifiedException;
    import com.example.exception.InvalidDataException;
    import com.example.exception.ResourceNotFoundException;
    import com.example.exception.model.Error;
    import jakarta.servlet.http.HttpServletRequest;
    
    @ControllerAdvice
    public class GlobalExceptionHandlerController {
    
      @ExceptionHandler(ResourceNotFoundException.class)
      public ResponseEntity<Object> resourceNotFound(ResourceNotFoundException ex,
          HttpServletRequest request) {
        Error error = new Error();
        error.setMessage(ex.getMessage());
        error.setTimestamp(new Date().getTime());
        error.setStatus(HttpStatus.NOT_FOUND.value());
        return new ResponseEntity<>(error, null, HttpStatus.NOT_FOUND);
      }
    
      @ExceptionHandler(InvalidDataException.class)
      public ResponseEntity<Object> invalidData(InvalidDataException ex, HttpServletRequest request) {
        Error error = new Error();
        error.setMessage(ex.getMessage());
        error.setTimestamp(new Date().getTime());
        error.setStatus(HttpStatus.BAD_REQUEST.value());
        return new ResponseEntity<>(error, null, HttpStatus.BAD_REQUEST);
      }
    
      @ExceptionHandler(DataMissingException.class)
      public ResponseEntity<Object> dataMissing(DataMissingException ex, HttpServletRequest request) {
        Error error = new Error();
        error.setMessage(ex.getMessage());
        error.setTimestamp(new Date().getTime());
        error.setStatus(HttpStatus.BAD_REQUEST.value());
        return new ResponseEntity<>(error, null, HttpStatus.BAD_REQUEST);
      }
    
      @ExceptionHandler(DataNotModifiedException.class)
      public ResponseEntity<Object> dataNotModified(DataNotModifiedException ex,
          HttpServletRequest request) {
        Error error = new Error();
        error.setMessage(ex.getMessage());
        error.setTimestamp(new Date().getTime());
        error.setStatus(HttpStatus.BAD_REQUEST.value());
        return new ResponseEntity<>(error, null, HttpStatus.BAD_REQUEST);
      }
    
    }

    Here, the class is annotated with @ControllerAdvice, which indicates that this class will provide advice (global exception handling) across all controllers. The methods within the class are annotated with @ExceptionHandler, which specifies that these methods will handle specific exceptions when they occur. In each method, a specific exception is caught (ResourceNotFoundException, MethodArgumentNotValidException, or DataMissingException). The method then creates an Error object, which is a custom model class that we earlier.

    The information from the caught exception is used to populate the Error object. In this example, the error message from the caught exception is set as the message in the Error object. The current timestamp is set using new Date().getTime(), and the appropriate HTTP status code is also set (e.g., HttpStatus.NOT_FOUND.value() for ResourceNotFoundException).

    Finally, a ResponseEntity is created, wrapping the Error object, and returned with the appropriate HTTP status code. This way, when one of these exceptions occurs, the framework will call the corresponding handler method to generate an error response with the necessary details.


    Next, create a utility class named CommonUtils. This class contains methods for converting dates to strings and strings to dates, as well as handling invalid data through a custom exception:

    package com.example.student.util;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import com.example.exception.InvalidDataException;
    
    public class CommonUtils {
    
      public static String convertDateToString(Date date) {
        if (date == null) {
          return "";
        }
        String pattern = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
      }
    
      public static Date convertStringToDate(String date) {
        if (date == null || date.isEmpty()) {
          return null;
        }
        String pattern = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setLenient(false); // Disallow lenient parsing to ensure strict matching
    
        try {
          // Attempt to parse the date with the specified pattern
          return sdf.parse(date);
    
        } catch (ParseException e) {
          // If parsing fails, it means the date does not match the pattern,
          throw new InvalidDataException("dateOfBirth must be in yyyy-mm-dd format.");
        }
      }
    
    }

    Create a service interface that defines the contract for the StudentService. Create a new interface called StudentService:

    package com.example.student.service;
    
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import com.example.student.model.StudentRequest;
    import com.example.student.model.StudentResponse;
    
    public interface StudentService {
    
    	StudentResponse addStudent(StudentRequest studentRequest);
    
    	StudentResponse updateStudent(StudentRequest studentRequest);
    
    	void deleteStudent(String studentId);
    
    	StudentResponse getStudentById(String studentId);
    
    	Page<StudentResponse> getAllStudents(Pageable pageable);
    
    }

    Create an implementation class that implements the StudentService interface and handles the business logic. Let's create a class called StudentServiceImpl:

    package com.example.student.service.impl;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageImpl;
    import org.springframework.data.domain.Pageable;
    import org.springframework.stereotype.Service;
    import com.example.exception.DataMissingException;
    import com.example.exception.DataNotModifiedException;
    import com.example.exception.ResourceNotFoundException;
    import com.example.student.entity.Student;
    import com.example.student.model.StudentRequest;
    import com.example.student.model.StudentResponse;
    import com.example.student.repository.StudentRepository;
    import com.example.student.service.StudentService;
    import com.example.student.util.CommonUtils;
    
    @Service
    public class StudentServiceImpl implements StudentService {
      private static final Logger LOGGER = LoggerFactory.getLogger(StudentServiceImpl.class);
    
      @Autowired
      private StudentRepository studentRepository;
    
      @Override
      public StudentResponse addStudent(StudentRequest studentRequest) {
        LOGGER.info("addStudent invoked...");
    
        if (studentRequest.getFirstName() == null || studentRequest.getFirstName().isEmpty()) {
          throw new DataMissingException("firstName is required.");
        }
        if (studentRequest.getLastName() == null || studentRequest.getLastName().isEmpty()) {
          throw new DataMissingException("lastName is required.");
        }
        if (studentRequest.getEmail() == null || studentRequest.getEmail().isEmpty()) {
          throw new DataMissingException("email is required.");
        }
    
        Student student = Student.builder().firstName(studentRequest.getFirstName())
            .lastName(studentRequest.getLastName()).email(studentRequest.getEmail())
            .mobileNumber(studentRequest.getMobileNumber())
            .dateOfBirth(CommonUtils.convertStringToDate(studentRequest.getDateOfBirth())).build();
    
        student = studentRepository.save(student);
    
        return StudentResponse.builder().studentId(student.getId())
            .firstName(student.getFirstName() != null ? student.getFirstName() : "")
            .lastName(student.getLastName() != null ? student.getLastName() : "")
            .email(student.getEmail() != null ? student.getEmail() : "")
            .mobileNumber(student.getMobileNumber())
            .dateOfBirth(CommonUtils.convertDateToString(student.getDateOfBirth()))
            .created(student.getCreated() != null ? student.getCreated() : null)
            .modified(student.getModified() != null ? student.getModified() : null)
            .createdBy(student.getCreatedBy() != null ? student.getCreatedBy() : "")
            .modifiedBy(student.getModifiedBy() != null ? student.getModifiedBy() : null).build();
      }
    
      @Override
      public StudentResponse updateStudent(StudentRequest studentRequest) {
        LOGGER.info("updateStudent invoked...");
    
        if (studentRequest.getStudentId() == null) {
          throw new IllegalArgumentException("studentId is required.");
        }
    
        Optional<Student> studentOpt = studentRepository.findById(studentRequest.getStudentId());
        if (!studentOpt.isPresent()) {
          throw new ResourceNotFoundException("student not found.");
        }
    
        Student existingStudent = studentOpt.get();
        boolean modified = false;
    
        if (studentRequest.getFirstName() != null && !studentRequest.getFirstName().contentEquals(
            existingStudent.getFirstName() != null ? existingStudent.getFirstName() : "")) {
          modified = true;
          existingStudent.setFirstName(studentRequest.getFirstName());
        }
        if (studentRequest.getLastName() != null && !studentRequest.getLastName().contentEquals(
            existingStudent.getLastName() != null ? existingStudent.getLastName() : "")) {
          modified = true;
          existingStudent.setLastName(studentRequest.getLastName());
        }
        if (studentRequest.getEmail() != null && !studentRequest.getEmail()
            .contentEquals(existingStudent.getEmail() != null ? existingStudent.getEmail() : "")) {
          modified = true;
          existingStudent.setEmail(studentRequest.getEmail());
        }
        if (studentRequest.getMobileNumber() != null && !studentRequest.getMobileNumber().contentEquals(
            existingStudent.getMobileNumber() != null ? existingStudent.getMobileNumber() : "")) {
          modified = true;
          existingStudent.setMobileNumber(studentRequest.getMobileNumber());
        }
        if (studentRequest.getDateOfBirth() != null && !studentRequest.getDateOfBirth().equals(
            existingStudent.getDateOfBirth() != null ? existingStudent.getDateOfBirth() : null)) {
          modified = true;
          existingStudent
              .setDateOfBirth(CommonUtils.convertStringToDate(studentRequest.getDateOfBirth()));
        }
    
        if (!modified) {
          throw new DataNotModifiedException("Data not modified because it is the same in the database.");
        }
    
        existingStudent = studentRepository.save(existingStudent);
    
        return StudentResponse.builder().studentId(existingStudent.getId())
            .firstName(existingStudent.getFirstName() != null ? existingStudent.getFirstName() : "")
            .lastName(existingStudent.getLastName() != null ? existingStudent.getLastName() : "")
            .email(existingStudent.getEmail() != null ? existingStudent.getEmail() : "")
            .mobileNumber(existingStudent.getMobileNumber())
            .dateOfBirth(CommonUtils.convertDateToString(existingStudent.getDateOfBirth()))
            .created(existingStudent.getCreated() != null ? existingStudent.getCreated() : null)
            .modified(existingStudent.getModified() != null ? existingStudent.getModified() : null)
            .createdBy(existingStudent.getCreatedBy() != null ? existingStudent.getCreatedBy() : "")
            .modifiedBy(
                existingStudent.getModifiedBy() != null ? existingStudent.getModifiedBy() : null)
            .build();
      }
    
      @Override
      public void deleteStudent(String studentId) {
        LOGGER.info("deleteStudent invoked...");
        if (studentId == null) {
          throw new IllegalArgumentException("studentId is required.");
        }
        Optional<Student> studentOpt = studentRepository.findById(studentId);
        if (!studentOpt.isPresent()) {
          throw new ResourceNotFoundException("student not found.");
        }
        studentRepository.deleteById(studentId);
      }
    
      @Override
      public StudentResponse getStudentById(String studentId) {
        LOGGER.info("getStudentById invoked...");
        if (studentId == null) {
          throw new IllegalArgumentException("studentId is required.");
        }
    
        Optional<Student> studentOpt = studentRepository.findById(studentId);
        if (!studentOpt.isPresent()) {
          throw new ResourceNotFoundException("student not found.");
        }
    
        Student existingStudent = studentOpt.get();
    
        return StudentResponse.builder().studentId(existingStudent.getId())
            .firstName(existingStudent.getFirstName() != null ? existingStudent.getFirstName() : "")
            .lastName(existingStudent.getLastName() != null ? existingStudent.getLastName() : "")
            .email(existingStudent.getEmail() != null ? existingStudent.getEmail() : "")
            .mobileNumber(existingStudent.getMobileNumber())
            .dateOfBirth(CommonUtils.convertDateToString(existingStudent.getDateOfBirth()))
            .created(existingStudent.getCreated() != null ? existingStudent.getCreated() : null)
            .modified(existingStudent.getModified() != null ? existingStudent.getModified() : null)
            .createdBy(existingStudent.getCreatedBy() != null ? existingStudent.getCreatedBy() : "")
            .modifiedBy(
                existingStudent.getModifiedBy() != null ? existingStudent.getModifiedBy() : null)
            .build();
      }
    
      @Override
      public Page<StudentResponse> getAllStudents(Pageable pageable) {
        LOGGER.info("getAllStudents invoked...");
        
        Page<Student> studentsPage = studentRepository.findAll(pageable);
    
        List<StudentResponse> studentsResponse = new ArrayList<>();
        Page<StudentResponse> studentsResponsePage = new PageImpl<>(studentsResponse, pageable, 0);
    
        if (studentsPage != null && !studentsPage.isEmpty()) {
    
          studentsPage.getContent().forEach(student -> {
    
            StudentResponse studentResponse = StudentResponse.builder().studentId(student.getId())
                .firstName(student.getFirstName() != null ? student.getFirstName() : "")
                .lastName(student.getLastName() != null ? student.getLastName() : "")
                .email(student.getEmail() != null ? student.getEmail() : "")
                .mobileNumber(student.getMobileNumber())
                .dateOfBirth(CommonUtils.convertDateToString(student.getDateOfBirth()))
                .created(student.getCreated() != null ? student.getCreated() : null)
                .modified(student.getModified() != null ? student.getModified() : null)
                .createdBy(student.getCreatedBy() != null ? student.getCreatedBy() : "")
                .modifiedBy(student.getModifiedBy() != null ? student.getModifiedBy() : null).build();
    
            studentsResponse.add(studentResponse);
          });
          studentsResponsePage =
              new PageImpl<>(studentsResponse, pageable, studentsPage.getTotalElements());
        }
        return studentsResponsePage;
      }
    
    }

    Create a controller class named StudentController. It will handle HTTP requests and interact with the StudentService:

    package com.example.student.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.web.PageableDefault;
    import org.springframework.data.web.SortDefault;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.PutMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import com.example.student.model.StudentRequest;
    import com.example.student.model.StudentResponse;
    import com.example.student.service.StudentService;
    
    @RequestMapping(path = "/students")
    @RestController
    public class StudentController {
    
      @Autowired
      private StudentService studentService;
    
      @PostMapping(path = "/add")
      public ResponseEntity<StudentResponse> addStudent(@RequestBody StudentRequest studentRequest) {
        return ResponseEntity.ok(studentService.addStudent(studentRequest));
      }
    
      @PutMapping(path = "/update")
      public ResponseEntity<StudentResponse> updateStudent(@RequestBody StudentRequest studentRequest) {
        return ResponseEntity.ok(studentService.updateStudent(studentRequest));
      }
    
      @DeleteMapping(path = "/{studentId}/delete")
      public void deleteStudent(@PathVariable(name = "studentId") String studentId) {
        studentService.deleteStudent(studentId);
      }
    
      @GetMapping(path = "/{studentId}")
      public ResponseEntity<StudentResponse> getStudent(
          @PathVariable(name = "studentId") String studentId) {
        return ResponseEntity.ok(studentService.getStudentById(studentId));
      }
    
      @GetMapping(path = "/all")
      public ResponseEntity<Page<StudentResponse>> getStudents(
          @PageableDefault(page = 0, size = 30) @SortDefault.SortDefaults({
              @SortDefault(sort = "modified", direction = Sort.Direction.DESC)}) Pageable pageable) {
    
        return ResponseEntity.ok(studentService.getAllStudents(pageable));
      }
    
    }

    Annotate the main class with @EnableMongoAuditing annotation. It is used to enable auditing in JPA entities. Auditing allows automatic population of specific fields such as created and updated in JPA entities based on the current date and time. It is commonly used to keep track of when an entity was created or last modified. The main class should look like this:

    package com.example;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.data.mongodb.config.EnableMongoAuditing;
    
    @EnableMongoAuditing
    @SpringBootApplication
    public class ExampleMongodbApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(ExampleMongodbApplication.class, args);
    	}
    
    }

  11. Run and Test your Application:
  12. Use your IDE's build tools (Maven or Gradle) to build your project and resolve dependencies. Once the build is successful, run the main class of your application. The Spring Boot application will start and deploy on an embedded web server (Tomcat) automatically. You should see logs indicating that the application has started.

    Use API testing tools (example: Postman) to test your application's endpoints and verify that your application is functioning as expected based on the implemented logic.

Congratulations! You have successfully created and run a Spring Boot project using Spring Initializr. You can continue developing your application by adding more features, configuring additional dependencies, and deploying it to various environments as needed.