ZK With MongoDB Part 2 - Using Morphia
Ashish Dasnurkar, Engineer, Potix Corporation
January 18, 2011
ZK 5
Introduction
Part 1 introduced you how to write a non-relation database driven ZK application. In particular, I used mongoDB and its Java driver low level APIs. The problem with that approach was I had to manually convert results returned from Java driver APIs to model Javabean instances. Wouldn't it be better if we could just talk to database in terms on POJOs? Morphia, a type-safe Java library does exactly that. It allows mapping Javabean objects to/from mongoDB. Let see how we can use it in our TODO sample application
Using Morphia
Follow the dependencies documentation to include Morphia in your project. I use maven so I simply included following dependency in my pom.xml
<dependency>
<groupId>com.google.code.morphia</groupId>
<artifactId>morphia</artifactId>
<version>0.99</version>
</dependency>
View
View part remains the same as in Part 1. Only change is I have a new controller to use morphia for managing task CRUD operations.
<window title="To do list" width="640px" border="normal" apply="org.zkoss.mongodb.controller.MongoDBMorphiaDemoCtrl">
<listbox id="tasks" multiple="true" rows="10">
<listhead>
<listheader label="Item" />
<listheader label="Priority" width="50px" />
<listheader label="Date" width="90px" />
</listhead>
</listbox>
<groupbox>
<caption label="Event" />
Item: <textbox id="name" constraint="no empty" cols="25" />
Priority: <intbox id="priority" cols="1" constraint="no empty"/>
Date: <datebox id="date" cols="8" constraint="no empty"/>
<button id="add" label="Add" />
<button id="update" label="Update" />
<button id="delete" label="Delete" />
</groupbox>
</window>
Model
Like Hibernate, Morphia uses annotations for defining mapping between POJO and MongoDB document templates. Below I annotate Task Javabean properties with Morphia annotations
@Entity("tasks")
public class Task {
@Id
private ObjectId id;
@Indexed(value = IndexDirection.ASC, name = "taskName", unique = true)
private String name;
@Indexed(value = IndexDirection.ASC, name = "taskPriority")
private int priority;
@Indexed(value = IndexDirection.ASC, name = "executionDate")
private Date executionDate;
// getters and setters
}
Here Entity annotation defines mongoDB collection in which Task Javabean will be stored. Id annotation marks a field in an @Entity to be the id field in mongoDB. MongoDB will auto assign a unique id into it. Indexed annotation defines Javabean property is to be indexed. More on Morphia annotations, refer to here.
Now, as in Part 1 we need a DAO to make persistence calls to MongoDB as it is a good practice to encapsulate persistence calls within DAO so that calling code (controller in this case) can use it without knowing the underlying details. Morphia has a built-in support for DAO interface in the form of BasicDAO implementation of it. This abstract class implements all the basic CRUD methods on model objects. I can just extend from this BasicDAO and since it uses generics to define a parameter class I wouldn't even need to cast the results returned from this DAO methods. Below is my TaskDAO implementation