Views

Microservice Using Spring Boot, Hibernate and MongoDB Database

Microservice Using Spring Boot, Hibernate and MongoDB Database
Page content

In this article, I will develop a Microservice Application using Spring Boot Framework and MongoDB Database and expose all CRUD (Create, Read, Update, Delete) Operations as the REST APIs.

Spring Boot Framework will serve as back-end server and I will be using No SQL Database known as MongoDB Database for persisting(storing) the data.

By the end of this article, you would learn about how to:

  • Configure Hibernate to work with No SQL Database and persist the data.

Overview

This article is based on my previous article Microservice Using Spring Boot, Hibernate and H2 Database, where I have explained how to expose the REST API using Spring Boot Framework and using the Relational Database like H2 Database for persisting(storing) the data.

In this article I will be explaining how to use No SQL Databases like MongoDB to persist the data, instead of Relational Database. Basic functionalities of the Microservice remains same, as explained in previous article. Please do read that once, before continuing here.

If you have no time to read this article completely, but want to try the code for yourself, GitHub location is provided here.


About MongoDB

Mongo DB stores data as documents and hence falls into a class of databases that are called Document Oriented Databases. There is also a broad category of database known as No SQL Databases.

A Relational Database has a typical schema design that shows number of tables and the relationship between these tables, while in MongoDB there is no concept of relationship.


Performance Analysis Between MongoDB and RDBMS

Relational Database (RDBMS) MongoDB Database
We have multiple schemas and, in each schema, we create tables to store data MongoDB is a document-oriented database in which data is written in BSON format which is a JSON like format
Tables are used to store elements Collection is used to store data
Slower, compared to MongoDB Almost 100 times faster than Traditional Relational Databases

Terminologies between RDBMS and MongoDB

The following table shows the relationship of RDBMS terminology with MongoDB.

Relational Database (RDBMS) MongoDB Database
Database Database
Table Collection
Tuple/Row Document
Column Field
Table Join $lookup, embedded document
Primary Key Primary Key (Default key _id provided by MongoDB itself)
SELECT INTO NEW_TABLE $out
MERGE INTO TABLE $merge

Things to consider while designing MongoDB schema

  • Always design schema according to user requirements.
  • Do join on write operations not on read operations.
  • Objects which you want to use together, should be combined into one document. Otherwise, they should be separated (make sure that there should not be need of joins).
  • Optimize your schema for more frequent use cases.
  • Do complex aggregation in the schema.
  • You should duplicate the data but, in a limit, because disc space is cheaper than compute time.

Installation

MongoDB Community Server for the windows can be downloaded from here.

Choose the On-Premises and select Version – Latest current, Platform – Windows, Package – msi and click on download.

mongo-installer.jpeg
MongoDB Installer

Once download is complete, double click the downloaded mongodb-windows-x86_64-4.4.2-signed.msi file and follow the on-screen instructions to complete the installation.


Running the MongoDB Server

Open the Command Prompt (PowerShell) and check the version of the installed MongoDB, using the command:

mongo --version

mongo-version.jpeg
MongoDB Version Check

Now start the MongoDB Database Server using the command:

mongod --dbpath "<<DATA_DIRECTORY>>"

A Data Directory is required in MongoDB to store all the information; hence we need to specify the –dbpath attribute. Default location for Data Directory is C:\data\db. If you want to put the data in different location, then specify the location using –dbpath attribute.

If we get the message “Waiting for connection” in the console, then our MongoDB database server is up and running successfully.

mongo-console.jpeg
MongoDB Database Server Up

Open another Command Prompt (PowerShell) and start the MongoDB shell, using the command: mongo

MongoDB Shell is now open. We can execute all our MongoDB queries and commands here.

mongo-shell.jpeg
MongoDB Shell

Some useful MongoDB commands

Command Description
show dbs show database names
show collections show collections in current database
show users show users in current database
show profile show most recent system.profile entries with time >= 1ms
show logs show the accessible logger names
show log [name] prints out the last segment of log in memory, ‘global’ is default
use <db_name> set current database
db check the currently selected database
db.createCollection(name, options) create collection. MongoDB creates collection automatically when you insert some documents.
db.<collection_name>.insert({key: value}) insert a document into the collection. {key:value} is the document
db.<collection_name>.find() list objects(documents) in collection <collection_name>
db.<collection_name>.find( { <field1>: <value> } ) list objects(documents) in <collection_name>.
<field>: <1 or true> - Specifies the inclusion of a field.
<field>: <0 or false> - Specifies the exclusion of a field.
db.<collection_name>.update(SELECTION_CRITERIA, UPDATED_DATA) to update or modify the existing documents of a collection.
SELECTION_CRITERIA – The selection criteria for the update.
UPDATED_DATA – The modifications to apply.
db.<collection_name>.remove (DELETION_CRITERIA, JustOne) to delete documents from a collection.
DELETION_CRITERIA – to remove the documents from the collection.
JustOne - It removes only one document when set to true or 1
it result of the last line evaluated; use to further iterate
db.<collection_name>.drop() drop a collection from a database
Db.dropDatabase() drops the currently used database
DBQuery.shellBatchSize = x set default number of items to display on shell
exit quit the mongo shell

Working with MongoDB

In MongoDB you don’t need to create a database manually because MongoDB will create it automatically when you save the value into the defined collection at first time.

  • Create a new Database using the command:
use testDB

mongo-use-db.jpeg
Create a new database

  • To check the currently selected database, use the command:
db

mongo-db.jpeg
Check Current Database

  • Check the database list, by using the command:
show dbs

mongo-show-dbs.jpeg
Show Databases List

Here, the database I created(above) “testDB” is not present in the list because, empty databases are not displayed. Insert at-least one document into it to display that database.

  • Insert documents (records) to database, using the command:
db.<collection_name>.insert({key: value})

Since I am already using the testDB database, I can directly use insert statement, else first I need to select the database and then the insert command.

If you want to insert multiple documents in a collection, you have to pass an array of documents using the below command.

db.<collection_name>.insert()

mongo-insert.jpeg
Insert Document

  • Now if you check the database list, you will see your testDB listed.

    mongo-latest-show-dbs.jpeg
    Show Database List

  • To check the collections, use the command:

show collections

mongo-show-collections.jpeg
Show Collections List in a Database

  • To list objects in your collections, use the command:
db.<collection_name>.find()

mongo-find.jpeg
Find the Collection

As you can see above, an _id is the unique identifier for the document and is generated automatically by the MongoDB.

The ObjectId is a 12-byte hexadecimal value, consists of:

  1. A 4-byte timestamp value, representing the ObjectId’s creation, measured in seconds since the Unix epoch
  2. A 5-byte random value
  3. A 3-byte incrementing counter, initialized to a random value
  • To drop the database, first get into the database to be dropped and then use the drop database command:
db.dropDatabase()

mongo-drop-database.jpeg
Dropping the Database


Using MongoDB in Spring Boot

Now that we have some understanding of the MongoDB and its commands, lets us see how we can replace our Relational Database in the project mentioned here with MongoDB Database.

We need to make some changes to our existing project, in order to make it compatible with MongoDB.

Update the pom.xml

Update the pom.xml by adding the following dependency

1<dependency>
2	<groupId>org.springframework.boot</groupId>
3	<artifactId>spring-boot-starter-data-mongodb</artifactId>
4</dependency>

Update the POJO Model Classes

  1. model.Tasks
 1@Document
 2public class Tasks {
 3    
 4    @Id
 5    private String systemTasksId;
 6    private String title;
 7    private String description;
 8    private LocalDate creationDate;
 9    private LocalDate dueDate;
10    private String status;
11    private Set<TodoTaskComments> todoTaskCommentsSet;
12}

Let us look at the highlighted lines

  • @Entity is replaced with @Document- Because everything is stored as document in MongoDB.
  • We don’t need @GeneratedValue on the primary key, as MongoDB would generate the primary key (_id- hexadecimal alphanumeric value) automatically, as already seen.
  • Since the Primary Key generated by MongoDB is a hexadecimal alphanumeric value, Primary Key needs to be a String.
  • MongoDB works with flat structure. When defining the relationship, there are two methods that work in MongoDB (We do not need any sort of relationship mappings (One-To-Many, Many-To-Many, One-To-One)):
    1. The Child Object can be directly called into the Parent Object(as shown above).
    2. The Controlling Object (Parent Object) can have a org.springframework.data.mongodb.core.mapping.DBRef or @DBRef Annotation on the Child Object.
  1. model.TodoTaskComments
1@Document
2public class TodoTaskComments {
3    @Id
4    private String todoTaskCommentsId;
5
6    private String taskComments;
7    private LocalDate creationDate;
8}
  • Since we are not working with the Relationship Mappings, we need not define the reverse mapping in the Child Object.

Update Repository Interfaces

  1. repository.TasksRepository
1@Repository
2public interface TasksRepository extends MongoRepository<Tasks, String> { }
  1. repository.TodoTaskCommentsRepository
1@Repository
2public interface TodoTaskCommentsRepository extends MongoRepository<TodoTaskComments, String> { }
  • Extend the MongoRepository, instead of JPARepository.

Update the application.properties

Update the database properties in /src/main/resources/application.properties

1spring.data.mongodb.database=todo-app
2spring.data.mongodb.port=27017
3spring.data.mongodb.host=localhost

If we don’t specify any database name(as in todo-app here), MongoDB server will create a default database called “test”, when inserting first set of document.

Once we have completed these configurations, we are ready to persist the data from the Spring Boot into MongoDB database.

Add Data into MongoDB Database

Open Command Prompt and start the MongoDB database as given here.

Once the mongo console is open, check the available databases.

mongo-spring-boot-show-dbs.jpeg
Show Database List

Now start the Spring Boot server in the IDE. Once the server starts, use create API on any Rest Client and add one entry.

HTTP MethodPOST
Endpoint URLhttp://localhost:8080/todo-app/tasks
Request HeaderContent-type: application/json
Request Body{
  "title": "Testing the Application",
  "description": "Testing the Application",
  "dueDate": "2022-05-31",
  "status": "NOT_STARTED",
  "todoTaskCommentsSet": []
}

Response from server

mongo-spring-boot-create-api.jpeg
Create API on MongoDB

Now check the database and you will see the new database created named todo-app. When you browse through this database, you will see collections and one entry added.

mongo-spring-boot-after-insert.jpeg
Mongo DB after insertion of document
This is the output on the Mongo console:

 1{ 
 2  "_id" : ObjectId("628744e3b0159e382a4365fb"), 
 3  "title" : "Testing the Application", 
 4  "description" : "Testing the Application", 
 5  "creationDate" : ISODate("2022-05-19T18:30:00Z"), 
 6  "dueDate" : ISODate("2022-05-30T18:30:00Z"), 
 7  "status" : "NOT_STARTED", 
 8  "todoTaskCommentsSet" : [ ], 
 9  "_class" : "com.myzonesoft.todo.microservice.model.Tasks" 
10}

Update the existing Data in MongoDB Database

Use Update API on any Rest Client and update an object.

HTTP Method PUT
Endpoint URL http://localhost:8080/todo-app/tasks
Request Header Content-type: application/json
Request Body {
  "id": <"system Id from the table">,
  "title": "Testing the Application",
  "description": "Testing the Application",
  "creationDate": "2022-05-20",
  "dueDate": "2022-05-31",
  "status": "IN_PROGRESS",
  "todoTaskCommentsSet": [{
    "taskComments": "Testing comments 1"
  }]
}

mongo-spring-boot-update-api.jpeg
Update API on MongoDB

Now check the database console, you will see collections and one entry updated.

mongo-spring-boot-after-update.jpeg
Mongo DB after update of document

This is the output on the Mongo console:

 1{ 
 2  "_id" : ObjectId("628744e3b0159e382a4365fb"), 
 3  "title" : "Testing the Application", 
 4  "description" : "Testing the Application", 
 5  "creationDate" : ISODate("2022-05-19T18:30:00Z"), 
 6  "dueDate" : ISODate("2022-05-30T18:30:00Z"), 
 7  "status" : "IN_PROGRESS", 
 8  "todoTaskCommentsSet" : [ 
 9    { 
10      "_id" : ObjectId("6287492fb0159e382a4365fc"), 
11      "taskComments" : "Testing comments 1", 
12      "creationDate" : ISODate("2022-05-19T18:30:00Z") 
13    } 
14  ], 
15  "_class" : "com.myzonesoft.todo.microservice.model.Tasks" 
16}
17
18{ 
19  "_id" : ObjectId("6287492fb0159e382a4365fc"), 
20  "taskComments" : "Testing comments 1", 
21  "creationDate" : ISODate("2022-05-19T18:30:00Z"), 
22  "_class" : "com.myzonesoft.todo.microservice.model.TodoTaskComments" 
23}

As you can see, it iterates through all the Child Objects and displays the result.

Congratulations, you have successfully persisted data into MongoDB database.


Conclusion

With this we have come to an end of this article and we have learned how to persist the data in MongoDB Database, using the same Spring Boot Microservice Project created earlier.

We only made few changes related to database and overall functionality and code related to REST API microservice was untouched.

Complete code for this project can be found at GitHub here. Go ahead and clone it.

Instructions on how to clone and run the project are provided on the GitHub page.