Spring Data Rest + AngularJS + MongoDB

Hello everybody, this time i took little long time to post an article here. Here i came up with a very powerful integration pack called “Integration of Spring data rest with AngularJS and MongoDB”. Now a days this combination is best suited for SPA – “Single Page Application” with light weight back end support with mongodb. Now we will have a Jump start into the tutorial. this tutorial will assume the prior basic knowledge of

  • Java8
  • Spring & Spring Data Rest
  • MongoDB

the project structure looks as below.
SpringAngularJSProj

Before proceeding with the Spring integration with angularjs and mongodb, please install mongodb and start the mongodb server. if everything goes well server startup should look as below.
mongodb_server_start

Now install any GUI client for mongodb for easy access, we can even access mongodb with out client but this is for better user experience. I personally use “Robomongo” and once you connect Robomongo to MongoDB server that will look as below.
robomongo

Once everything is ready and inplace, let us start with writing the code. I have used Maven to manage the dependencies and hence the pom.xml looks as below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spark.ng.spring</groupId>
	<artifactId>AngularSpring</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>AngularSpring</name>
	<description>AngularSpring</description>

	<properties>
		<spring-version>4.1.2.RELEASE</spring-version>
		<jdk-version>1.8</jdk-version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring-version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-core</artifactId>
			<version>2.3.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>1.5.2.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-rest-webmvc</artifactId>
			<version>2.3.0.RELEASE</version>
		</dependency>

		<!-- mongodb java driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>2.11.0</version>
		</dependency>
		
		<!-- Servlet 3.x api -->
		 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        
	</dependencies>

	<build>
		<finalName>AngularSpring</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<warSourceDirectory>src/main/webapp</warSourceDirectory>
					<warName>AngularSpring</warName>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Once the dependencies are downloaded let us start with the configuration. In this tutorial i am moving with NoXml style of configuration.
ApplicationConfig.java

/**
 * 
 */
package com.spark.ng.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import com.mongodb.MongoClient;

/**
 * @author Mantha Pavan Kumar
 *
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages={"com.spark.ng.spring"})
@EnableMongoRepositories(basePackages={"com.spark.ng.spring.data.repository"})
@Import(RepositoryRestMvcConfiguration.class)
public class ApplicationConfig {
	
	public @Bean
    MongoDbFactory mongoDbFactory() throws Exception {
		MongoClient mongoClient = new MongoClient("localhost",27017);
        return new SimpleMongoDbFactory(mongoClient, "Customer");
    }

    public @Bean
    MongoTemplate mongoTemplate() throws Exception {
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
        return mongoTemplate;
    }
    
	@Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".html");
 
        return viewResolver;
    }
}

WebApplicationConfig.java

/**
 * 
 */
package com.spark.ng.spring.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * @author Mantha Pavan Kumar
 *
 */
public class WebApplicationConfig implements WebApplicationInitializer{

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		
		AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
		annotationConfigWebApplicationContext.register(ApplicationConfig.class);
		annotationConfigWebApplicationContext.setServletContext(servletContext);
		
		ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(annotationConfigWebApplicationContext));
		servlet.setLoadOnStartup(1);
		servlet.addMapping("/rest/*");
	}

}

With the above two files we are done with the configuration part. Let us talk about ApplicationConfig.java a little more in deep. At the top of the class please take a close look, i have annotated the class with “@EnableWebMvc”, which will enable all “@Component” based class and scans them when the application is loaded by the web container. The annotation “@EnableWebMvc” is equivalent to “”. Moving little forward “@ComponentScan” will scan all the @Component based classes. Now comes the “@EnableMongoRepositories” which will load all the repositories. Finally we have imported a core class from the Spring API called “RepositoryRestMvcConfiguration” this is the class responsible for converting the domain objects back and forth to JSON format and acts as a communication bridge between clint(browser) & backend. In this class we have innitialised two beans called “MongoDBFactory” & “MongoTemplate” since if we have any operation to do apart from Repository implementation then we can use of “MongoTemplate” object to fulfill that.

Let us have a look at the domain object Customer.java

/**
 * 
 */
package com.spark.ng.spring.domain.objects;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;


/**
 * @author PavanKumar Mantha
 *
 */
@Document(collection="customer")
public class Customer {

	@Id
	@Field
	private String id;
	@Field
	private String customerId;
	@Field
	private String firstName;
	@Field
	private String lastName;
	@Field
	private String contactAddr;
	@Field
	private String mobileNumber;
	

	/**
	 * @return the customerId
	 */
	public String getCustomerId() {
		return customerId;
	}

	/**
	 * @param customerId
	 *            the customerId to set
	 */
	public void setCustomerId(String customerId) {
		this.customerId = customerId;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the contactAddr
	 */
	public String getContactAddr() {
		return contactAddr;
	}

	/**
	 * @param contactAddr
	 *            the contactAddr to set
	 */
	public void setContactAddr(String contactAddr) {
		this.contactAddr = contactAddr;
	}

	/**
	 * @return the mobileNumber
	 */
	public String getMobileNumber() {
		return mobileNumber;
	}

	/**
	 * @param mobileNumber
	 *            the mobileNumber to set
	 */
	public void setMobileNumber(String mobileNumber) {
		this.mobileNumber = mobileNumber;
	}

}

A generic Response object with which we can send messages back to browser.

/**
 * 
 */
package com.spark.ng.spring.domain.objects;

/**
 * @author Sony
 *
 */
public class ResponseObject {

	private String message;

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message
	 *            the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

}

The class “ApplicationRepositoryUtil.java will get us all the objects that are required using the @Autowired annotation.

/**
 * 
 */
package com.spark.ng.spring.data.repository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

/**
 * @author Sony
 *
 */
@Service
public class ApplicationRepositoryUtil {

	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private CustomerRepository customerRepository;

	/**
	 * @return the mongoTemplate
	 */
	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}

	/**
	 * @return the customerRepository
	 */
	public CustomerRepository getCustomerRepository() {
		return customerRepository;
	}

}

Here comes the exact repository that we were talking from little while. Please observe the repository carefully. Its an interface extending one more interface called “MongoRepository”.The goal of Spring Data repository abstraction is to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.The central interface in Spring Data repository abstraction is Repository (probably not that much of a surprise). It takes the domain class to manage as well as the id type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The CrudRepository provides sophisticated CRUD functionality for the entity class that is being managed. MongoRepository extends the basic CrudRepository.

/**
 * 
 */
package com.spark.ng.spring.data.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;

import com.spark.ng.spring.domain.objects.Customer;

/**
 * @author Sony
 *
 */
@RepositoryRestResource(collectionResourceRel="customer",path="customer")
public interface CustomerRepository extends MongoRepository<Customer, Integer> {

}

Here is a simple controller that will receive the requests from clients and delegates them to appropriate layers.

/**
 * 
 */
package com.spark.ng.spring.controller;

import java.util.function.Supplier;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.spark.ng.spring.data.repository.ApplicationRepositoryUtil;
import com.spark.ng.spring.domain.objects.ResponseObject;

/**
 * @author Sony
 *
 */
@RestController
@RequestMapping(value = "/app")
public class ApplicationController {

	@Autowired
	ApplicationRepositoryUtil applicationRepositoryUtil;

	@RequestMapping("/test")
	public ResponseObject handleRequest() {
		System.out
				.println("---------------------Testing method called---------------- Mongo Template :"
						+ applicationRepositoryUtil.getMongoTemplate()
						+ " Repository Object : "
						+ applicationRepositoryUtil.getCustomerRepository());
		Supplier<ResponseObject> supplier = ResponseObject::new;
		ResponseObject responseObject = supplier.get();

		responseObject.setMessage("Sample Data Object");
		return responseObject;

	}
}

Now we done with the java part and now its time for us to write the Html and java script. please download latest AngularJS library and include the “angular.min.js” inside your project, after including please write a file called “mongo.module.js” and out the following content into it.

/**
 * 
 */
var myApp = angular.module('myApp', ['controllers']);

Now write an AngularJs controller which is responsible for firing the Ajax request to the Spring and get the data in REST format. create a folder called “controllers” and create a file “controllers.js” and put the following content into it.

/**
 * 
 */

var controllersModule = angular.module('controllers', []);

controllersModule.controller('SampleController', function($scope) {
	console.log('Sample Load done !');
});

controllersModule.controller('ajaxController', function($scope, $http) {
	$http.get('/AngularSpring/rest/customer/').success(function(data) {
		console.log(data);
	});
});

Let us create an Html file “index.html” with the below content

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="ISO-8859-1">
<title>Index Page</title>
<script type="text/javascript" src="jsLib/angular.min.js"></script>
</head>
<body>
	<div ng-controller="SampleController">Hello AngularJs</div>
	<div ng-controller="ajaxController">Hello Spring Data Rest & MongoDB</div>

</body>
<script type="text/javascript" src="mongo.module.js"></script>
<script type="text/javascript" src="controllers/controllers.js"></script>
</html>

That is it guys we are done from coding part and its time for us to build the application and deploy it to server.
Once we deploy the application into the server, please install an Add on to firefox or chrome called “RESTClient” from which we can test our repositories are working or not.
RestClient

Once you fire the request as shown in the above screen shot, we should get the response from the service as below.
REST_Response

Now try to open our page “index.html” and in firebug console we could see the same response as above which means pur angularjs is firing the request and our Spring repositories are responding to the request.

index

Happy Spring Data REst + AngularJS + MongoDB 🙂
Happy Coding 🙂

Spring Data JPA to persist the domain objects

Hi all,These days i am taking little time to post new topics as i am doing little R&D in spring’s latest projects like ‘SpringBoot’ and ‘SpringData’. Now here is the post which will explain about ‘SpringData’. Please follow the code little carefully as i wrote block comments in order to better understand the logic. this project is designed under Maven,Spring4.1.1.RELEASE, Eclipse Luna and Tomcat 8.0.11.

Please find the below is the project structure, First let us start with required dependencies for the project as shown below.
project_structure
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.spark.spring.data.rest</groupId>
	<artifactId>SpringDataRest</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringDataRest</name>
	<description>SpringDataRest</description>
	
	<repositories>
		<repository>
			<id>repository.jboss.org-public</id>
			<name>JBoss repository</name>
			<url>https://repository.jboss.org/nexus/content/groups/public</url>
		</repository>
	</repositories>
	<properties>
		<hibernate.version>4.0.1.Final</hibernate.version>
		<mysql.connector.version>5.1.9</mysql.connector.version>
		<slf4j.version>1.6.1</slf4j.version>
		<spring.version>4.1.1.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<!-- Spring Framework -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- Spring MVC -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>
		<!-- Spring Data JPA -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.0.2.RELEASE</version>
		</dependency>
		<!-- Hibernate -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.0.1.GA</version>
		</dependency>

		<!-- H2 Database -->
		<!-- <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> 
			<version>1.3.160</version> </dependency> -->
		<!-- MySQL JDBC connector -->
		<!-- If you want to use MySQL, uncomment this dependency declation. -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.connector.version}</version>
		</dependency>
		<!-- PostgreSQL JDBC 4 -->
		<!-- If you don't want to use PostgreSQL, uncomment this dependency declaration. -->
		<!-- <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> 
			<version>9.0-801.jdbc4</version> </dependency> -->
		<!-- BoneCP -->
		<dependency>
			<groupId>com.jolbox</groupId>
			<artifactId>bonecp</artifactId>
			<version>0.7.1.RELEASE</version>
		</dependency>
		<!-- Servlet API 3.0 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- Logging dependencies -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<!-- Testing Dependencies -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.9</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>SpringData</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Let us carry on with all the configurations required by the project and then with the actual logic. below is the code for the ‘application.properties’ file and ‘applicationContext.xml’
application.properties this file is fully loaded with all properties which are required by major databases, just uncomment what ever you need and use it.

# The default database is H2 memory database but I have also
# added configuration needed to use either MySQL and PostgreSQL.
 
#Database Configuration

#db.driver=org.h2.Driver
db.driver=com.mysql.jdbc.Driver
#db.driver=org.postgresql.Driver
#db.driver=oralce.jdbc.driver.OracleDriver

#db.url=jdbc:h2:mem:datajpa
db.url=jdbc:mysql://localhost:3306/test
#db.url=jdbc:postgresql://localhost/datajpa
#db.url=jdbc:oracle:thin:@localhost:1521:xe

db.username=?
db.password=?
 
#Hibernate Configuration
#hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.dialect=org.hibernate.dialect.MySQLDialect
#hibernate.dialect=org.hibernate.dialect.OracleDialect
#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

hibernate.format_sql=true
hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
hibernate.show_sql=true
 
#MessageSource
message.source.basename=i18n/messages
message.source.use.code.as.default.message=true
 
#EntityManager
#Declares the base package of the entity classes
entitymanager.packages.to.scan=com.spark.spring.data.domain

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
	
	<!-- Configures the location of static resources such as css files. Requires 
		Spring Framework 3.0 or higher. -->
	<mvc:resources mapping="/static/**" location="/static/" />

	<!-- Ensures that dispatcher servlet can be mapped to '/' and static resources 
		are still served by the containers default servlet. Requires Spring Framework 
		3.0 or higher. -->
	<mvc:default-servlet-handler />

	<!-- Configures Spring Data JPA and sets the base package of repositories. -->
	<jpa:repositories base-package="com.spark.spring.data.repositories" />

</beans>

Now it is time for us to write Java Configurations for Spring to initialize various bean objects and to recognize various annotations in the project, also let us write a configuration for servlet initialization instead of traditional web.xml

ApplicationConfig.java : this class is responsible for initialising the DataSource,JpaTransactionManager and for setting Hibernate properties

/**
 * 
 */
package com.spark.spring.data.config;

import java.util.Properties;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.hibernate.ejb.HibernatePersistence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * An application context Java configuration class. The usage of Java configuration
 * requires Spring Framework 3.0 or higher with following exceptions:
 * <ul>
 *     <li>@EnableWebMvc annotation requires Spring Framework 3.1</li>
 * </ul>
 * @author Pavan Kumar Mantha
 */
@Configuration
@ComponentScan(basePackages = {"com.spark.spring.data"})
@EnableWebMvc
@ImportResource("classpath:applicationContext.xml")
@PropertySource("classpath:application.properties")
public class ApplicationConfig {

	private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
    private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
 
    private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
    private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
 
    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
    private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
 
    @Resource
    private Environment environment;
    
    @Bean
    public DataSource getDataSource(){
    	DriverManagerDataSource dataSource = new DriverManagerDataSource();
    	dataSource.setDriverClassName(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
        dataSource.setUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
        dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
        dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
 
        return dataSource;
    }
    
    @Bean(name="transactionManager")
    public JpaTransactionManager getJpaTransactionManager() throws ClassNotFoundException{
    	JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    	jpaTransactionManager.setEntityManagerFactory(getLocalEntityManagerFactoryBean().getObject());
    	return jpaTransactionManager;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean getLocalEntityManagerFactoryBean(){
    	LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    	entityManagerFactoryBean.setDataSource(getDataSource());
    	entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
    	entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
    	
    	Properties properties = new Properties();
    	properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
    	properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
    	properties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
    	properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
    	
    	entityManagerFactoryBean.setJpaProperties(properties);
    	return entityManagerFactoryBean;
    }
    
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
 
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
        viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
 
        return viewResolver;
    }
}

WebContextInit.java : This class is responsible for initializing the servlet(front controller) and remember this will only work with servlet 3 containers only.

/**
 * 
 */
package com.spark.spring.data.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

/**
 * Web application Java configuration class. The usage of web application
 * initializer requires Spring Framework 3.1 and Servlet 3.0.
 * @author Pavan kumar Mantha
 */
public class WebContextInit implements WebApplicationInitializer {

	private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
	private static final String DISPATCHER_SERVLET_MAPPING = "/rest/*";

	@Override
	public void onStartup(ServletContext servletContext)
			throws ServletException {
		AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext = new AnnotationConfigWebApplicationContext();
		annotationConfigWebApplicationContext.register(ApplicationConfig.class);

		ServletRegistration.Dynamic dynamic = servletContext.addServlet(
				DISPATCHER_SERVLET_NAME, new DispatcherServlet(
						annotationConfigWebApplicationContext));
		dynamic.setLoadOnStartup(1);
		dynamic.addMapping(DISPATCHER_SERVLET_MAPPING);
		
	}

}

Now let us design our domain objects, data transfer objects and User defined Exceptions. In this case our domain object is “Person.java”. in this class we have a static inner class which is called “Builder”, the responsibility of Builder class is to create Person objects and return them.
Person.java

/**
 * 
 */
package com.spark.spring.data.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

/**
 * An entity class which contains the information of a single person.
 * 
 * @author Pavan kumar Mantha
 */
@Entity
@Table(name = "person")
public class Person {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(name = "first_name", nullable = false)
	private String firstName;

	@Column(name = "last_name", nullable = false)
	private String lastName;

	@Version
	private long version = 0;

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName
	 *            the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName
	 *            the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the version
	 */
	public long getVersion() {
		return version;
	}

	/**
	 * @param version
	 *            the version to set
	 */
	public void setVersion(long version) {
		this.version = version;
	}
	
	/**
	 * this method returns the builder object
	 */
	public static Builder getBuilder(String firstName,String lastName){
		return new Builder(firstName, lastName);
	}
	
	/**
	 * A Builder class that is used to create Person Object.
	 */
	public static class Builder{
		
		Person person;
		
		public Builder(String firstName, String lastName) {
			person = new Person();
			person.firstName = firstName;
			person.lastName = lastName;
		}
		
		public Person build(){
			return person;
		}
	}

}

PersonDTO.java : This class is responsible to inject the data from the front end and then push that to builder class and get the original person domain object

/**
 * 
 */
package com.spark.spring.data.domain;

import org.hibernate.validator.constraints.NotEmpty;

/**
 * A DTO object which is used as a form object
 * in create person and edit person forms.
 * @author Pavan Kumar Mantha
 */
public class PersonDTO {

	private Long id;

	@NotEmpty
	private String firstName;

	@NotEmpty
	private String lastName;

	public PersonDTO() {

	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

PersonNotFoundException.java

/**
 * 
 */
package com.spark.spring.data.exceptions;

/**
 * @author Pavan Kumar mantha
 *
 */
public class PersonNotFoundException extends Exception{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public PersonNotFoundException() {
		super();
	}
	
	@Override
	public synchronized Throwable getCause() {
		return super.getCause();
	}
	
	@Override
	public String getMessage() {
		return super.getMessage();
	}
}

Since all our Domain Objects,DTO objects and custom exception types are in place, its time for us to write our Repository Interface. Spring Data has given an out of the box functionality for CRUD operations called CRUDRepository and there are many other Repositories which will extend from this base interface and one of them is “JpaRepository”. It is prety straight forward to design a repository all you have to do is to create an interface which extends the JpaRepository interface. The JpaRepository interface is a JPA specific extension to the Repository interface and it gives you the access to following methods which are used to implement the CRUD application:

delete(T entity) which deletes the entity given as a parameter.
findAll() which returns a list of entities.
findOne(ID id) which returns the entity using the id given a parameter as a search criteria.
save(T entity) which saves the entity given as a parameter.

PersonRepository.java

/**
 * 
 */
package com.spark.spring.data.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.spark.spring.data.domain.Person;

/**
 * Specifies methods used to obtain and modify person related information
 * which is stored in the database.
 * @author Pavan Kumar Mantha
 */
@Transactional(value="transactionManager",propagation=Propagation.NESTED)
public interface PersonRepository extends JpaRepository<Person, Long>{

}

Once we have our PersonRepository interface ready to use, let us start with service layer to hadle the business logic.
PersonService.java : This interface is responsible for basic operations on the domain object in connection with the underlying database.

/**
 * 
 */
package com.spark.spring.data.service;

import java.util.List;

import com.spark.spring.data.domain.Person;
import com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.exceptions.PersonNotFoundException;

/**
 * Declares methods used to obtain and modify person information.
 * @author Pavan Kumar Mantha
 */
public interface PersonService {

	/**
     * Creates a new person.
     * @param created   The information of the created person.
     * @return  The created person.
     */
    public Person create(PersonDTO personDTO);
 
    /**
     * Deletes a person.
     * @param personId  The id of the deleted person.
     * @return  The deleted person.
     * @throws PersonNotFoundException  if no person is found with the given id.
     */
    public Person delete(Long personId) throws PersonNotFoundException;
 
    /**
     * Finds all persons.
     * @return  A list of persons.
     */
    public List<Person> findAll();
 
    /**
     * Finds person by id.
     * @param id    The id of the wanted person.
     * @return  The found person. If no person is found, this method returns null.
     */
    public Person findById(Long id);
 
    /**
     * Updates the information of a person.
     * @param updated   The information of the updated person.
     * @return  The updated person.
     * @throws PersonNotFoundException  if no person is found with given id.
     */
    public Person update(PersonDTO personDTO) throws PersonNotFoundException;
}

The implmentation for the above service interface is as below.
Note : all the methods of interface are implemented with default definition and only create has the exact logic, the others are left for you people to implement.Also observer @Transactional annotation it is at the method level not at the class level.
Please observer that the PersonRepository class gets injected by the spring container and CRUD operation capability is provided by it.
PersonServiceImpl.java

/**
 * 
 */
package com.spark.spring.data.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.spark.spring.data.domain.Person;
import com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.exceptions.PersonNotFoundException;
import com.spark.spring.data.repositories.PersonRepository;
import com.spark.spring.data.service.PersonService;

/**
 * This implementation of the PersonService interface communicates with
 * the database by using a Spring Data JPA repository.
 * @author Pavan Kumar Mantha
 */
@Service(value="personService")
public class PersonServiceImpl implements PersonService{

	@Resource
	private PersonRepository personRepository;
	
	@Override
	@Transactional(value="transactionManager")
	public Person create(PersonDTO personDTO) {

		Person person = Person.getBuilder(personDTO.getFirstName(), personDTO.getLastName()).build();
		return personRepository.save(person);
	}

	@Override
	public Person delete(Long personId) throws PersonNotFoundException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Person> findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Person findById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Person update(PersonDTO personDTO) throws PersonNotFoundException {
		// TODO Auto-generated method stub
		return null;
	}

}

Now every thing is completed from logic point of view let us start with the controller class class to handle different request from client.
Please observe that i have hard coded the values from domain object here, in my next post i will be making this as dynamic, for time being this is for testing.

/**
 * 
 */
package com.spark.spring.data.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.spark.spring.data.domain.PersonDTO;
import com.spark.spring.data.service.PersonService;

/**
 * @author Pavan Kumar Mantha
 *
 */
@Controller
public class ApplicationController {

	@Autowired
	private PersonService personService;
	
	@RequestMapping(value="/create",method=RequestMethod.GET)
	public void create(){
		System.out.println("-------------------inside the method-----------------"+personService);
		PersonDTO personDTO = new PersonDTO();
		personDTO.setFirstName("Pavan Kumar");
		personDTO.setLastName("Mantha");
		personService.create(personDTO);
	}
}

Thats it guys we are done with coding part, now build the project get the war file and deploy it to server.If you see no errors in server console please issue below request from browser “http://localhost:8080/SpringData/rest/create&#8221;.

in server you should see as below.
server_console

and when you query database that should look as below.
database_op

In my next post i will be integrating this project with AngularJs as my front end with fully Ajax driven application.

Happy Coding, Happy Spring Data 🙂