Friday, September 16, 2011

Spring MVC: Integrating MySQL, MongoDB, RabbitMQ, and AJAX - Part 1

Introduction

In this article we will explore how to integrate MySQL, MongoDB, and RabbitMQ in a Spring MVC application using Spring Data JPA, Spring Data MongoDB, and Spring AMQP projects respectively. Then we'll add AJAX in the presentation layer using jQuery. For presenting tabular data, we will explore two jQuery plugins: DataTables and jQgrid. The jQgrid version will use Spring Cache support to boost performance. The ultimate purpose of this article is to demonstrate how to integrate these different projects in a single Spring MVC application.

Our application is a simple event management system for performing CRUD operations. When we talk of events, we're referring to the colloquial definition, i.e wedding event. The application's main data will be stored in a MySQL database using Hibernate as our ORM. We will use Spring Data JPA to simplify the data access layer. This means we don't need to implement our own data access objects.

Our application is also capable of broadcasting these events as simple text messages. To broadcast these events, we will use RabbitMQ as our messaging broker, and Spring AMQP for sending and receiving of messages.

No application is free from errors. Therefore, we've added error persistence capability using MongoDB. Our application has logging capabilities already, but we want the ability to analyze these errors later. Therefore, this is where MongoDB plays in. To simplify the data access layer, we will use Spring Data MongoDB, similar with Spring Data JPA.

Table of Contents

  1. Event Management
  2. Messaging support
  3. Error persistence
  4. Build and deploy

Frequently Asked Questions (FAQs)

  1. Q: What is JPA?
    A: See http://en.wikipedia.org/wiki/Java_Persistence_API
  2. Q: What is MongoDB?
    A: See http://www.mongodb.org
  3. Q: What is RabbitMQ?
    A: See http://www.rabbitmq.com
  4. Q: What is Spring Data?
    A: See http://www.springsource.org/spring-data
  5. Q: What is Spring Data - JPA?
    A: See http://www.springsource.org/spring-data/jpa
  6. Q: What is Spring Data - MongoDB?
    A: See http://static.springsource.org/spring-data/data-document/docs/current/reference/html
  7. Q: What is Spring AMQP?
    A: See http://www.springsource.org/spring-amqp
  8. Q: What is jQuery?
    A: http://jquery.com/
  9. Q: What is AJAX?
    A: http://en.wikipedia.org/wiki/Ajax_(programming)
  10. Q: What is Ehcache?
    A: http://ehcache.org/

Required Tools and Services

The following tools and services are essential in building and running our project:
  1. MySQL
  2. The application's main data will be stored in MySQL. If you don't have one yet, download and install one by visiting the MySQL home page, or use a pre-packaged setup via XAMPP or Wamp.
    • MySQL: http://www.mysql.com/downloads/
    • Wamp: http://www.wampserver.com
    • XAMPP: http://www.apachefriends.org
  3. RabbitMQ
  4. We will publish and listen for messages using RabbitMQ. If you don't have one yet, download and install one by visiting the RabbitMQ home page.
    • http://www.rabbitmq.com/download.html
  5. MongoDB
  6. We will persist errors using MongoDB. If you don't have one yet, download and install one by visiting the MongoDB home page.
    • http://www.mongodb.org/downloads
  7. Maven
  8. We will use Maven to build our project. If you don't have one yet, download and install one by visiting the Maven home page. You can also use SpringSource Tool Suite (STS), an Eclipse-powered IDE, which has Maven pre-installed.
    • Maven: http://maven.apache.org/download.html
    • STS: http://www.springsource.com/developer/sts

Screenshots

Before we dive into development, it's better if we first visualize what we will be developing.






Live Deployment in the Cloud

The best way to interact with the application is with a live deployment. Therefore, I have taken extra steps to deploy the project in the cloud via the excellent open platform Cloud Foundry. To access the project, visit http://spring-mysql-mongo-rabbit.cloudfoundry.com/

Project Structure

To see how we're going to structure the project, take a look at the following screenshot:


The project's source code is available at GitHub. You can access the project's repository at spring-mysql-mongo-rabbit-integration

Project Dependencies (pom.xml)

The pom.xml contains the project's dependencies. It's a long list but I will only show the relevant entries. As of Sept 17 2011, we're using the latest versions.

What is POM?
POM stands for "Project Object Model". It is an XML representation of a Maven project held in a file named pom.xml. See http://maven.apache.org/pom.html

To see the pom's entire contents, please check the attached Maven project at the end of this tutorial.

Development

The project will be divided into four parts:
  1. Event Management
  2. Messaging support
  3. Error persistence
  4. Build and deploy

A. Event Management

The Event Management is the core function of the system. And we're specifically referring to the CRUD operations. We will divide this stage in four sub-parts:
  1. Event Management
    • A1. Domain
    • A2. Service
    • A3. Controller
    • A4. View
      1. DataTables view
      2. jQgrid view
    • A5. Crosscutting Concerns

A1. Domain

The domain contains a simple Event class. By marking it with @Entity the class will be persisted in a relational database. Notice the class has validation constraints added. For example, the name field cannot be null.

Special attention is given to the date field. We've annotated it with @DateTimeFormat, a Spring conversion annotation (see Spring Reference 5.6.2.1 Format Annotation API) to help us serialize and deserialize JSON dates in the presentation layer.

Event.java


A2. Service

Before we start developing the service layer we need to create first the data access objects (DAOs) manually. We do this for every new project. Through time it becomes repetitive and tedious. Gladly, Spring has a solution: the Spring Data project.

Spring Data's purpose is to provide us ready-made data access objects for various database sources. All we need to do is extend an interface and we're good to go. This means we can start writing the service immediately (if needed).

Spring Data is not a single project, but rather it's composed of many different projects specifically catering to different types of databases (see http://www.springsource.org/spring-data). Since we're using MySQL and Hibernate we will use the Spring Data JPA project.

IEventRepository.java


IEventService.java


EventService.java


A3. Controller

We have a single controller, EventController, whose main purpose is to display the Event page. It also has methods for handling CRUD operations that are ultimately delegated to the EventService.

EventController.java


A4. View

I've provided two views for displaying Event records: a DataTables version and a jQgrid version. The purpose of having two views is to demonstrate Spring's flexibility and teach various ways of presenting tabular data.

To proceed, please choose your preferred view (a specific guide will be presented):
  1. DataTables view
  2. jQgrid view

JMeter Test

The main difference between these two views are the addition of cache to the jQgrid controller. To appreciate the difference, I've provided JMeter tests to gauge each controller's performance. Take note that this tests have nothing to do with the DataTables or jQgrid plugin. The tests are written so that it will only query the controllers without generating the presentation layer.

Small dataset (9 records):

Large dataset (4300+ records):

Notice in small datasets the difference in performance is almost trivial. However, in large datasets the difference is phenomenal. Adding a cache greatly improves the application's performance (of course this assumes that the same request will be called multiple times).

Click here to download the JMeter Test. To run this test, make sure to run only one test, i.e do the DataTables first, then the jQgrid, or vice versa.

What is JMeter?
Apache JMeter is open source software, a 100% pure Java desktop application designed to load test functional behavior and measure performance. Source: http://jakarta.apache.org/jmeter/

A5. Crosscutting Concerns

As mentioned earlier, no application is free from errors. To facilitate troubleshooting, a logging mechanism needs to be added. Typically we would place the logging mechanism across our existing classes. This is a crosscutting concern.

What is a crosscutting concern?
In computer science, cross-cutting concerns are aspects of a program which affect other concerns. These concerns often cannot be cleanly decomposed from the rest of the system in both the design and implementation, and can result in either scattering (code duplication), tangling (significant dependencies between systems), or both.

For instance, if writing an application for handling medical records, the bookkeeping and indexing of such records is a core concern, while logging a history of changes to the record database or user database, or an authentication system, would be cross-cutting concerns since they touch more parts of the program. See http://en.wikipedia.org/wiki/Cross-cutting_concern

To implement a clean way of logging our application, we will take advantage of Spring's CustomizableTraceInterceptor support as seen in the Spring Data JPA reference (Appendix B. Frequently asked questions).

By default CustomizableTraceInterceptor uses trace level for logging. If we want to change the logging level, we need to extend this class and override the writeToLog() method. We have created a sub-class TraceInterceptor and change the logging level to debug

TraceInterceptor.java


After creating the class, we declare it as a bean in the XML configuration. Notice we've configured the entry and exit signature patterns and the pointcut expressions to match. In other words, this will log all services and specific controllers.

trace-context.xml


Next Section

In the next section, we will add messaging support using RabbitMQ and Spring AMQP. To proceed to the next section, click here.
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC: Integrating MySQL, MongoDB, RabbitMQ, and AJAX - Part 1 ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

17 comments:

  1. Hi,

    Your blog has been so much useful for me.I learned a lot from the contents of your blog. Thanks a lot for providing such useful tutorials. Also it would be great if you provide some tutorials on Single Sign On using spring security and CAS server.
    Thanks

    ReplyDelete
  2. Thanks for the comments.

    @Anonymous, I will once I have the extra free time to write them :)

    ReplyDelete
  3. Excellent post and has helped me understanding ajax with spring integration.
    Where can I find the source code for Event management?

    ReplyDelete
  4. More specifically, I am wondering how you are posting an ajax call to spring controller with required form parameters and how do you populate the Datatable again with changes(add/edit etc). I did not see the getRecords implementation.

    Thanks a lot

    ReplyDelete
  5. hi!! i tested your source downloading from github..
    but when i starting program.pom.xml could not working
    this line does not working.
    please help me and thanks


    com.goldin.plugins
    maven-copy-plugin
    0.2.3

    ReplyDelete
  6. You need to enable the Evgeny Goldin Repository (see the repository section of the pom.xml)

    <repository>
    <id>evgeny-goldin.org</id>
    <name>Evgeny Goldin Repository</name>
    <url>http://evgeny-goldin.org/artifactory/repo/</url>
    </repository>

    If this doesn't work, please check the Maven-Copy-Plugin: http://evgeny-goldin.com/wiki/Maven-copy-plugin

    ReplyDelete
  7. I think the point anonymous was making, is that when downloading your code from Git (and without making any changes) it doesn't work because of the maven-copy-plugin issue. Not sure what you are expecting people to check on evgeny site. Is there something wrong in the way the repo is specified?

    ReplyDelete
  8. Hi Krams. Good article. I think the issue is because maven-copy is a plugin and not a dependency. Therefore i managed to compile using:-



    evgeny-goldin.org
    Evgeny Goldin Repository
    http://evgeny-goldin.org/artifactory/repo/

    ReplyDelete
    Replies
    1. sorry try again...use pluginRepositories and pluginRepository.

      Delete
    2. @Anonymous, thanks for the info. That has been brought to my attention as well in one of my recent tutorials. I've fixed the pom.xml. It should now have the maven-copy-plugin under the pluginRepositories section

      Delete
  9. Keep posting such kind of information on your blog. I bookmarked it for continuous visit. Thanks once again.
    html5 player

    ReplyDelete
  10. Hi KRams,

    Simply superb tutorials..keep rocking

    ReplyDelete
  11. I have read your blog its very attractive and impressive. I like it your blog.

    Spring online training Spring online training Spring Hibernate online training Spring Hibernate online training Java online training

    spring training in chennai spring hibernate training in chennai

    ReplyDelete
  12. BlueHost is ultimately the best hosting provider with plans for all of your hosting requirements.

    ReplyDelete