Top Tabs

Saturday, February 19, 2011

Spring Data - MongoDB Tutorial (1.0.0.M1)

Introduction

In this tutorial we will refactor an existing Spring MVC 3 - MongoDB application (see here) to use the newly released Spring Data Document 1.0.0.M1 for MongoDB. Our purpose here is to realize how Spring Data simplifies integration development with MongoDB. To appreciate Spring Data, it is advisable to know how to perform basic CRUD functions with native MongoDB support. And that's the reason why we'll be refactoring an existing Spring MVC 3 - MongoDB application.

MongoDB (from "humongous") is a scalable, high-performance, open source, document-oriented database. Written in C++, MongoDB features:

Document-oriented storage

Full Index Support

Replication & High Availability

Scale horizontally without compromising functionality.

Rich, document-based queries.

Atomic modifiers for contention-free performance.

Flexible aggregation and data processing.

Store files of any size without complicating your stack.

Enterprise class support, training, and consulting available.

Source: http://www.mongodb.org/

What is Spring Data - Document?

The Spring Data Document (or DATADOC) framework makes it easy to write Spring applications that use a Document store by eliminating the redundant tasks and boiler place code required for interacting with the store through Spring's excellent infrastructure support.

In a nutshell MongoDB uses JSON instead of SQL There's no static schema to create. All schemas are dynamic, meaning you create them on-the-fly. You can try a real-time online shell for MongoDB at http://try.mongodb.org/. Visit the official MongoDB site for a thorough discussion.

Prerequisites
In order to complete this tutorial, you will be required to install a copy of MongoDB. If you don't have one yet, grab a copy now by visiting http://www.mongodb.org/display/DOCS/Quickstart. Installation is really easy.

Development

Our application is a simple CRUD system for managing a list of Persons. Data is stored in MongoDB database. We'll start by declaring our domain objects. Then we'll discuss the service layer. And lastly we'll add the controllers.

The Domain Layer

Our application contains a single domain object named Person. It consists the following properties:

Warning!
In the original tutorial we used id to signify the primary identity of the Person. But in this tutorial we used pid instead. This is because when we use id with Spring Data, it messes up the id property by merging it with the built-in _id property of MongoDB.

For now, if you plan to use Spring Data, don't use id as your id field. Choose a different name instead. I have filed already an inquiry about this behavior in the Spring forums. See it here.

The Service Layer

Our service class contains the main changes in the original application. Instead of calling native MongoDB methods for performing CRUD operations, we use Spring Data's MongoTemplate instead.

What is MongoTemplate?

The template offers convenience methods and automatic mapping between MongoDB JSON documents and your domain classes. Out of the box, MongoTemplate uses a Java-based default converter but you can also write your own converter classes to be used for reading and storing domain objects.

The code should should be self-explanatory. Notice how Spring Data has reduced the amount of code. To appreciate this difference, let's do a comparison between using the traditional MongoDB and using Spring Data.

Run the Application

To run the application, open your browser and enter the following URL:

http://localhost:8080/spring-data-mongodb/krams/main/persons

You should see the following CRUD view:

Conclusion

That's it. We have successfully refactored our existing Spring MVC 3 - MongoDB application to use the newly released Spring Data Document 1.0 for MongoDB. We've compared side-by-side between the native MongoDB development and with the new Spring Data framework. We have seen how Spring Data has simplified our development further.

@Anonymous, I just tried right now with the following URL: http://localhost:8080/spring-data-mongodb/krams/main/persons I'm able to access it without issues. Do you have MongoDB running? Do you see any log output?

This was quite useful but isn't there a way to write my queries using plain json syntax as it is done in a mongo shell. It would be nice if the framework allows to pass the arguments to methods like find and findOne which are plain `json` strings but the results could be easily mapped to user objects.

Atharva, thanks for pointing that out. I know most NoSQL stores don't provide transactional support. I think this is an old remnant from my old projects. I have provided a note at the top of this article indicating a link to a much updated guide: http://krams915.blogspot.com/2012/01/spring-mvc-31-implement-crud-with_7897.html

I'm not really sure what the real cause of this problem. Are you using the latest libraries? I have already provided an updated version of this guide: http://krams915.blogspot.com/2012/01/spring-mvc-31-implement-crud-with_4739.html

I'm trying to tweak this to connect to my mongolab cloud DB, however the only way I can see to enter a password is to use mongo:db-factory in the mongo-config.xml. Whenever I do this however I get "no declaration can be found for element 'mongo:db-factory'".

How can I add username/password to connection details in order to connect to a remote mongodb, rather than localhost? Can you provide an example that connects to a free mongolab account?