Friday, January 20, 2012

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

Review

In the previous section, we have learned how to setup a MongoDB server in Windows and Ubuntu. In this section, we will discuss the project's structure, write the Java classes, and organize them in layers.


Project Structure

Our application is a Maven project and therefore follows Maven structure. As we create the classes, we've organized them in logical layers: domain, repository, service, and controller.

Here's a preview of our project's structure:

The Layers

Domain Layer

This layer contains two classes, User and Role. They represent our database collections, user and role respectively. We're using Spring Data MongoDB to simplify MongoDB access. And to optimize these classes for the framework, we've added the @Document annotation. If you're familiar with JPA, this is similar to the @Entity annotation.

Notice the User class has a reference to a Role property. In order to achieve that, we must annotate the field with @DBRef.



Mapping annotation overview
  • @Id - applied at the field level to mark the field used for identiy purpose.
  • @Document - applied at the class level to indicate this class is a candidate for mapping to the database. You can specify the name of the collection where the database will be stored.
  • @DBRef - applied at the field to indicate it is to be stored using a com.mongodb.DBRef.
Source: http://static.springsource.org/spring-data/data-document/docs/current/reference/html/

Controller Layer

This layer contains two controllers, MediatorController and UserController
  • MediatorController is responsible for redirecting requests to appropriate pages. This isn't really required but it's here for organizational purposes.
  • UserController is responsible for handling user-related requests such as adding and deleting of records



Service Layer

This layer contains two services, UserService and InitMongoService
  • UserService is our CRUD service for the user collection. All data access is delegated to the repositories
  • InitMongoService is used for initiliazing our database with sample data. Notice we're using the MongoTemplate itself instead of the Spring Data MongoDB-based repository. There is no difference between the two. In fact, it's simpler if we used Spring Data instead. But I have chosen MongoTemplate to show an alternative way of interacting with the database


Note
The mapping framework does not handle cascading saves. If you change an Account object that is referenced by a Person object, you must save the Account object separately. Calling save on the Person object will not automatically save the Account objects in the property accounts.

Source: Spring Data MongoDB Reference (7.3.3. Using DBRefs)

Repository Layer

This layer contains two repositories, UserRepository and RoleRepository. These are our data access objects (DAO). With the help of Spring Data MongoDB, Spring will automatically provide the actual implementation. Notice for custom methods we just have to add the method signature.

What is Spring Data MongoDB?
Spring Data for MongoDB is part of the umbrella Spring Data project which aims to provide a familiar and consistent Spring-based programming model for for new datastores while retaining store-specific features and capabilities. The Spring Data MongoDB project provides integration with the MongoDB document database. Key functional areas of Spring Data MongoDB are a POJO centric model for interacting with a MongoDB DBCollection and easily writing a Repository style data access layer

Source: http://www.springsource.org/spring-data/mongodb




Utility classes

TraceInterceptor class is an AOP-based utility class to help us debug our application. This is a subclass of CustomizableTraceInterceptor (see Spring Data JPA FAQ)



Next

In the next section, we will focus on the configuration files for enabling Spring MVC. 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 3) ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

17 comments:

  1. I have a question about UserListDto method on the Class UserController. In the methos you use a Dto for the User wich not exists.

    To run the example I've removed those lines and instead I've used return service.readAll()

    ReplyDelete
    Replies
    1. What do you mean by User? The class itself. It exists in the package org.krams.domain

      Delete
    2. You forgot to publish the code for UserListDto class and because of that userListDto.setUsers(service.readAll()) in UserController's getUsers() method is not recognized.

      Delete
  2. Dear Sir,

    Please provide UserListDto class. please provide to source code.zip link.

    Thanks in advance,

    ReplyDelete
    Replies
    1. Dear Sir,

      Thats, ok, I got the code for UserListDto. Thanks for your very nice tutorial, your effort helps us to learn new things. I like your all tutorials. I am keep visiting your website to learn new things :) Thanks you again sir.

      Delete
  3. Trying to get through this with the latest versions of Spring MVC and MongoDB. I've managed to get most of this tutorial working but the biggest problem I'm having right now is I get errors when it tries to Autowire the UserService in the UserController. It throws a "No matching bean of type [org.krams.service.UserService] found for dependency"

    ReplyDelete
    Replies
    1. D'oh - turns out my component-scan in the XML file wasn't set at the base class (I'd accidentally changed it to scan in the .controller package).

      So now I'm not getting an error, it's just not reading anything. When I call service.readAll() it returns no results. But the logs show that init() in InitMongoService is being called and it's working properly.

      Delete
    2. I suggest you login directly to your MongoDB via a terminal. Query it and verify that there's indeed data after the InitMongoService is executed.

      Delete
  4. I can't understand, where to find a UserListDto class code.

    ReplyDelete
    Replies
    1. It's under the org.krams.dto package. Check the directory screenshot above

      Delete
  5. Hi,
    Im using Spring Tool Suite 3.1.0.RELEASE for developing.
    I'm trying to open a Maven project but witout success.
    I have to choose one of some ArcheType for creating new Maven project.
    What can I do for creating new project as the one above?
    Thanks,
    Eyal.

    ReplyDelete
    Replies
    1. Creating the project first as a dynamic web project first then convert it to maven project, a lot of easier.

      sry for my english

      Delete
  6. Thank you for sharing !! : )

    I have a little question with @Autowired in UserService class.

    As i understand this annotation will map the declared object to the bean ,right ? but i didn't find any bean that reference to both userRepository and roleRepository.

    Can you teach me how this code work ? Thank a lot : D

    ReplyDelete
    Replies
    1. Spring will map the matching beans automagically. In part 4, I have declared a mongo:repositories element. That will automatically scan the packages for matching beans.

      Delete
  7. Hi,

    thanks for sharing! your tutorials are real good, fast and detailed.

    I'm trying to debug the application in ecliplse by:

    Debug As -> Maven Build....
    Goal->tomcat:run
    parameter -> forkMode=never

    but I always end up whit "Unable to install breakpoint due to missing line number attributes"

    This is the right way to debug it in eclipse?

    Thanks

    John

    ReplyDelete
  8. UserListDTO does not exists. You have to place it on this page..

    ReplyDelete
  9. Hi Krams,

    Will you please submit an SSO application with Spring

    ReplyDelete