In this post we are going to examine
Morphia as an Oject Document Mapper (ODM) tool for
MongoDB. We will map Java
Objects to MongoDB Documents. We will also perform basic Create, Read, Update and Delete (CRUD) with
To follow along this post, you should have a working installation of MongoDB on Windows and / or Linux.
This is a
gradle based project and we are using the standard Java project structure.
. |__src/ | |__main/ | | |__java/ | | | |__com/ | | | | |juliuskrah/ | | | | |__morphia/ | | | | | |__Application.java | | | | | |__config/ | | | | | | |__DataSourceConfig.java | | | | | |__entity/ | | | | | | |__Author.java | | | | | | |__Book.java | | | | | |__repository/ | | | | | | |__AuthorRepository.java | | | | | | |__BookRepository.java | | | | | | |__impl/ | | | | | | | |__AuthorRepositoryImpl.java | | | | | | | |__BookRepositoryImpl.java | | |__resources/ | | | |__application.yaml |__build.gradle
Before we can use
Morphia we need to add the dependency in our gradle buildscript.
To illustrate the use of
Morphia we will build a
Configure Spring Application
Let us start with setting up our Spring-Boot application
The above snippet starts up Spring-Boot with auto-configuration enabled.
Next we configure
Morphia for Spring-Boot.
Finally add the externalized configuration for the locally installed MongoDB database.
Object Document Mapping
With all the basic requirements out of the way, we can start mapping our Java Objects to MongoDB documents using
Book example. An author can write many books, and a book can have multiple authors. We will keep
this simple by focusing on an author with many books and not the inverse relationship.
There are two ways that Morphia can handle your classes: as top level entities or embedded in others. Any class
@Entity is treated as a top level document stored directly in a collection. Any class with
must have a field annotated with
@Id to define which field to use as the
_id value in the document written to
@Embedded indicates that the class will result in a subdocument inside another document.
do not require the presence of an
@Id field. We would not cover
@Embedded in this post.
There are a few things here to discuss and others we will defer to later sections. The above classes are annotated using
@Entity annotation so we know that it will be a top level document. In the annotation, you’ll see
"authors". By default, Morphia will use the class name as the collection name. If you pass a String instead, it will
use that value for the collection name. In this case, all
Book instances will be saved in to the
Author instances to the
authors collection instead.
@Indexes annotation lists which indexes Morphia should create. In this instance, we’re defining an index named
name on the field
name with the default ordering of ascending.
We have marked the
id field to be used as our primary key (the
_id field in the document). In this instance we are
using the Java driver type of
ObjectId as the ID type. The ID can be any type you would like but is generally
Long. There are two other annotations to cover but it should be pointed out now that
other than transient and static fields, Morphia will attempt to copy every field to a document bound for the database.
The simplest of the two remaining annotations is
@Property. This annotation is entirely optional. If you leave this
annotation off, Morphia will use the Java field name as the document field name. Often times this is fine. However,
some times you will want to change the document field name for any number of reasons. In those cases, you can use
@Property and pass it the name to be used when this class is serialized out to a document to be handed off to MongoDB.
This just leaves
@Reference. This annotation is telling Morphia that this field refers to other Morphia mapped
entities. In this case Morphia will store what MongoDB calls a
DBRef which is just a
collection name and key value. These referenced entities must already be saved or at least have an ID assigned or
Morphia will throw an exception.
Creating the CRUD repository
We will create a simple repository class to take care of our CRUD operations.
For the most part, you treat your Java objects just like you normally would. When you’re ready to write an object to the database, it’s as simple as this:
Morphia attempts to make your queries as type safe as possible. All of the details of converting your data are handled by Morphia directly and only rarely do you need to take additional action. The following example illustrates this:
There are two basic ways to update your data: insert/save a whole Entity or issue an update operation.
Updating (on the server)
The update method on
Datastore is used to issue a command to the server to change existing documents. The effects of
the update command are defined via
Here we are updating the
read instance obtained from the database and updating the
The above executes the update in the database without having to pull in the document. The
returned will contain various statistics about the update operation.
Updating (call create on an updated entity)
Updating data in MongoDB is as simple as updating your Java objects and then calling
datastore.save() with them
After everything else, removes are really quite simple. Removing just needs a query to find and delete the documents
in question and then tell the
Datastore to delete them:
The full class will look something like this:
In this post we saw the basic mapping between a java object and a MongoDB document. We also saw how to perform basic
CRUD operations using
As usual you can find the full example to this guide in the github repository. Until the next post, keep doing cool things .