Microservice Using Spring Boot, Hibernate and MongoDB Database
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.
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
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.
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.
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
- To check the currently selected database, use the command:
db
- Check the database list, by using the command:
show dbs
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()
-
Now if you check the database list, you will see your testDB listed.
-
To check the collections, use the command:
show collections
- To list objects in your collections, use the command:
db.<collection_name>.find()
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:
- A 4-byte timestamp value, representing the ObjectId’s creation, measured in seconds since the Unix epoch
- A 5-byte random value
- 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()
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
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)):
- The Child Object can be directly called into the Parent Object(as shown above).
- The Controlling Object (Parent Object) can have a
org.springframework.data.mongodb.core.mapping.DBRef
or@DBRef
Annotation on the Child Object.
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
repository.TasksRepository
1@Repository
2public interface TasksRepository extends MongoRepository<Tasks, String> { }
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.
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 Method | POST |
Endpoint URL | http://localhost:8080/todo-app/tasks |
Request Header | Content-type: application/json |
Request Body | { |
Response from server
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. 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 |
{
|
Now check the database console, you will see collections and one entry updated.
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.