Friday, January 20, 2012

Spring MVC 3.1 - Implement CRUD with Spring Data MongoDB (Part 1)

In this tutorial, we will create a simple CRUD application using Spring 3.1 and MongoDB. In particular, we will use Spring MVC to develop the web application and Spring Data MongoDB for the repository.


Dependencies

  • Spring core 3.1.0.RELEASE
  • Spring Data MongoDB 1.0.0.RELEASE
  • MongoDB (server) 2.0.2
  • MongoDB (Java driver) 2.7.2
  • See pom.xml for details

Github

To access the source code, please visit the project's Github repository (click here)

Functional Specs

Before we start, let's define our application's specs as follows:
  • A CRUD page for managing users
  • Use AJAX to avoid page refresh
  • Users have roles. They are either admin or regular (default)
  • Everyone can create new users and edit existing ones
  • When editing, users can only edit first name, last name, and role fields
  • A username is assumed to be unique

Here's our Use Case diagram:
[User]-(View)
[User]-(Add) 
[User]-(Edit) 
[User]-(Delete) 

Database

If you're new to MongoDB and coming from a SQL-background, please take some time to read the following resource SQL to Mongo Mapping Chart. It's a comparison between SQL and MongoDB.

We have two collections (tables in SQL): user and role. The user collection contains personal information of each user; whereas the role collection contains role values for each user where a value of 1 represents an admin and a value of 2 represents a regular user.

Here's the Class diagram:
# Cool UML Diagram
[User|id;firstName;lastName;username;password;role{bg:orange}]1--1> [Role|id;role{bg:green}]

User document

Below is the JSON structure of the User document after Spring Data MongoDB has created the collection:
{ 
   "_id" : "" , 
   "_class" : "org.krams.domain.User"
   "firstName" : ""
   "lastName" : ""
   "username" : ""
   "password" : "" , 
   "role" : { "$ref" : "role" , "$id" : "" }
}
Notice the role property is a reference to a Role record as indicated by $ref: role property.

Role document

Below is the JSON structure of the Role document after Spring Data MongoDB has created the collection:
{ 
   "_id" : ""
   "_class" : "org.krams.domain.Role"
   "role" : ""
}

Screenshots

Let's preview how the application will look like after it's finished. This is also a good way to clarify further the application's specs.

The Activity diagram:

http://yuml.me/diagram/activity/(start)-%3E%3Cd1%3Eview-%3E(Show%20Records)-%3E%7Ca%7C-%3E(end),%20%3Cd1%3Eadd-%3E(Show%20Form)-%3E%7Ca%7C,%20%3Cd1%3Eedit-%3E%3Cd2%3Ehas%20selected-%3E(Show%20Form)-%3E%7Ca%7C,%20%3Cd2%3Eno%20record%20selected-%3E(Popup%20Alert)-%3E%7Ca%7C,%20%3Cd1%3Edelete-%3E%3Cd3%3Ehas%20selected-%3E(Delete%20Record)-%3E%7Ca%7C,%20%3Cd3%3Eno%20record%20selected-%3E(Popup%20Alert)-%3E%7Ca%7C.

Entry page
The entry page is the primary page that users will see. It contains a table showing user records and four buttons for adding, editing, deleting, and reloading data. All interactions will happen in this page.

Entry page

Edit existing record
When user clicks the Edit button, an Edit Record form shall appear after the table.

Edit record form

When a user submits the form, a success or failure alert should appear.

Success alert

When the operation is successful, the update record should reflect on the table.

Edited record appears on the table

Create new record
When a user clicks the New button, a Create New Record form shall appear after the table.

Create new record form

When a user submits the form, a success or failure alert should appear.

Success alert

When the operation is successful, the new record should appear on the table.

New record shows on the form

Delete record
When user clicks the Delete button, a success or failure alert should appear.

Success alert

Reload record
When user clicks the Reload button, the data on the table should be reloaded.

Errors
When user clicks the Edit or Delete button without selecting a record first, a "Select a record first!" alert should appear.

Error alert

Next

In the next section, we will study how to setup a MongoDB server both in Windows and Ubuntu. Click here to proceed.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3.1 - Implement CRUD with Spring Data MongoDB (Part 1) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

15 comments:

  1. You should have a look to my Spring MVC 3.1 - Spring Data - MongoDB XML free example application https://github.com/sdeleuze/spring-backbone-todo

    ReplyDelete
  2. @Bouiaw, thanks. I'm looking at it right now. It would be great if you can write a blog about this one.

    ReplyDelete
  3. @Bouiaw, the use of XML-less configuration is great. However, I find it anticlimactic when it comes to the repository. I was expecting you would utilize the Spring Data MongoDB repository support, but instead you used directly the MongoTemplate. Though nothing's wrong with that, I find that part somewhat wanting.

    ReplyDelete
  4. Question: Do you know if there is any way to prevent Spring from storing the fully qualified classname under _class in the database (example: "_class" : "org.krams.domain.User") when inserting? Or will the mapping stop working by doing this?

    ReplyDelete
  5. @Anonymous, I have to investigate further if that's possible

    ReplyDelete
  6. I was wondering if you have any example integrating MongoDB with Spring Security.

    ReplyDelete
    Replies
    1. Sorry, I don't have any yet. Is it possible? I think so. You just have to provide a custom user details service which delegates the data access to MongoDB dao or repository.

      Delete
  7. Hi,

    great example that has helped me a lot. What I cannot find anywhere is how to make a multiple-field search form (search by field1, field2... fieldN if they are given values).

    You can search by any combination of any of the fiels (with AND...). I've tried to do it through a "findByField1AndField2AndField3And....". The idea was that if I put "null" in one field, that field would not be used in the search, but Mondo does it, so it cannot be done with this approach.

    How, if any combination of fields to find could be created in the form, could it be done? Do I need to create every combination of "findBy...." that are possible to be searched for?

    Thanks in advance :)

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hi, nice work.
    I noticed that the new/create functionality added a new Role for each new user instead of referencing an existing role.

    I fixed this by
    1) removing the role save in UserService.create:
    public User create(User user) {
    user.setId(UUID.randomUUID().toString());
    // user.getRole().setId(UUID.randomUUID().toString());
    ...
    // roleRepository.save(user.getRole());
    return userRepository.save(user);
    }

    2) adding methods
    Role findByRole(Integer role); to RoleRepository
    public Role getRole(Integer role) {
    return roleRepository.findByRole(role);
    } to UserService
    3) replacing the new Role with the role lookup in UserController.create:
    // Role newRole = new Role();
    // newRole.setRole(role);
    Role newRole = service.getRole(role);

    Cheers,
    John

    ReplyDelete
  10. using codebase to a tomcat maven build there appears to be ajax related issues on any type of form submission using your js code. Appears to only work on chrome base browsers. (well having said that only used ff and chromium and it was not working in ff) Didnt bother investigating the underlying issues though. Does work smoothly in chromium.

    ReplyDelete
  11. Hello!

    When I've imported source code on my local PC using Spring Tool Suite, there're errors on jquery-1.6.4.min.js

    ReplyDelete
  12. hi krams,

    Thanks for your work.
    started with the thymeleaf one - brilliant tutorial.

    Now I wanted to look at "Spring Data Redis" and noticed it links to "Spring MVC 3.1 and Spring Data MongoDB".
    accidentally or on purpose?

    ReplyDelete
  13. Good sample.

    but, New and Edit function are not work.
    not apear alert window and reload users Webpage only.
    thank you.

    ReplyDelete
  14. What the hell is this????????????
    I am clicking on the link Spring redis but always the mongoDB tutorial opens. Please try to remove that, for our convenience.
    Thanks and regards

    ReplyDelete