Spring Data MongoDB with Spring MVC

Below is the steps to create a Spring MVC application with MongoDB
1. Create MongoDB Entity
2. Define MongoDB DataSource
3. Define MongoDBTemplate
4. Create MongoDB Repository interface
5. Implement MongoDB Repository interface
6. Define your MongoDB Controller
7. Test MongoDB DataSource
8. Test MongoDBTemplate
9. Test MongoDB Repository

Create MongoDB Entity

package com.example.model;

import java.math.BigInteger;
import java.util.Date;

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.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="CustomerActivity")
public class CustomerActivity implements java.io.Serializable {
	
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="id", nullable=false, unique=true)
	private BigInteger id;
	
	@Column(name="customerId", nullable=false)
	private String customerId;
	
	@Column(name="activityDescription") 
	private String activityDescription;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="activityTime")
	private Date activityTime;
	
	@Column(name="activityType")
	private String activityType; //ActivityType
	
	@Column(name="systemName")
	private String systemName;
	
	@Column(name="systemUrl")
	private String systemUrl;

	public CustomerActivity(String customerId, String activityDescription, Date activityTime, String activityType, String systemName, String systemUrl) {
		this.customerId = customerId;
		this.activityDescription = activityDescription;
		this.activityTime = activityTime;
		this.activityType = activityType;
		this.systemName = systemName;
		this.systemUrl = systemUrl;
	}

	public BigInteger getId() {
		return id;
	}

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

	public String getCustomerId() {
		return customerId;
	}

	public void setCustomerId(String customerId) {
		this.customerId = customerId;
	}

	public String getActivityDescription() {
		return activityDescription;
	}

	public void setActivityDescription(String activityDescription) {
		this.activityDescription = activityDescription;
	}

	public Date getActivityTime() {
		return activityTime;
	}

	public void setActivityTime(Date activityTime) {
		this.activityTime = activityTime;
	}

	public String getActivityType() {
		return activityType;
	}

	public void setActivityType(String activityType) {
		this.activityType = activityType;
	}

	public String getSystemName() {
		return systemName;
	}

	public void setSystemName(String systemName) {
		this.systemName = systemName;
	}

	public String getSystemUrl() {
		return systemUrl;
	}

	public void setSystemUrl(String systemUrl) {
		this.systemUrl = systemUrl;
	}
}

Define MongoDB DataSource

package com.example.config;

import javax.inject.Inject;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.Mongo;

@PropertySource("classpath:services.properties")
@Configuration
@Profile("default")
public class MongoDataSourceConfiguration {
	
	    @Inject Environment environment;
	    
	    @Bean(name="local")
	    public MongoDbFactory mongoDbFactoryLocal() throws Exception {
	        String dbName = environment.getProperty("mongo.db");
	        String host = environment.getProperty("mongo.host");
	        Mongo mongo = new Mongo(host);
	        return new SimpleMongoDbFactory(mongo, dbName);
	    }
}

Define MongoDBTemplate

package com.example.mongo;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.context.annotation.*;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import com.example.config.MongoDataSourceConfiguration;

/**
 * @author Thys Michels
 */
@Configuration
@Import( { MongoDataSourceConfiguration.class })
@EnableMongoRepositories
public class MongoRepositoryConfiguration {
	
    @Inject @Named("local") private MongoDbFactory mongoDbFactoryLocal;
	
    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactoryLocal);
    }

    @Bean
    public GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) throws Exception {
        return new GridFsTemplate(mongoDbFactory, mongoTemplate.getConverter());
    }
}

Create MongoDB Repository interface

package com.example.service;

import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import com.example.model.CustomerActivity;

public interface CustomerActivityRepository {
	void updateCustomerActivity(BigInteger id, String customerId, String activityDescription, String activityType, String systemName, String systemUrl);
    void updateCustomerActivities(List<CustomerActivity> customersToUpdate);
    CustomerActivity getCustomerActivityById(BigInteger customerId);
    Collection<CustomerActivity> getAllCustomerActivities();
    void createCustomerActivity(String customerId, String activityDescription, Date activityTime, String activityType, String systemName, String systemUrl);
    void deleteCustomerActivity(BigInteger customerId);
    void createCustomerActivity(CustomerActivity newCustomer);
    void bulkCreateCustomerActivity(List<CustomerActivity> customers);
    List<CustomerActivity> findCustomerActivityByQuery(String query);
    void deleteCustomerActivities(List<CustomerActivity> customerToDelete);
    List<CustomerActivity> getPaginatedCustomerActivities(Integer currentPage, Integer totalPerPage);
    int getTotalRecords();
	List<String> getPaginationSequence();
	List<CustomerActivity> findCustomerActivityByCustomerId(String customerid);
}

Implement MongoDB Repository interface

package com.example.service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.example.model.CustomerActivity;
import com.example.mongo.MongoRepositoryConfiguration;

@Repository
@Import( { MongoRepositoryConfiguration.class })
@Qualifier("mongoRepository")
public class CustomerActivityRepositoryImpl implements CustomerActivityRepository{	
	
	@Inject MongoTemplate mongoTemplate;
	
	Class<CustomerActivity> entityClass = CustomerActivity.class;
	
	Collection<CustomerActivity> customerActivity = new ArrayList<CustomerActivity>();
	
	@Override
	public void updateCustomerActivity(BigInteger id, String customerId, String activityDescription,  String activityType, String systemName, String systemUrl) {
		CustomerActivity updateCustomerActivity = this.getCustomerActivityById(id);
		updateCustomerActivity.setCustomerId(customerId);
		updateCustomerActivity.setActivityDescription(activityDescription);
		
		updateCustomerActivity.setActivityType(activityType);
		updateCustomerActivity.setSystemName(systemName);
		updateCustomerActivity.setSystemUrl(systemUrl);
		mongoTemplate.save(updateCustomerActivity);
	}

	@Override
	public void updateCustomerActivities(List<CustomerActivity> customerActivitiesToUpdate) {
		for (CustomerActivity customerActivity : customerActivitiesToUpdate){
			Update updateCustomerActivity = new Update();
			updateCustomerActivity.push("customerId", customerActivity.getCustomerId());
			updateCustomerActivity.push("activityDescription", customerActivity.getActivityDescription());
			updateCustomerActivity.push("activityTime", customerActivity.getActivityTime());
			updateCustomerActivity.push("activityType", customerActivity.getActivityType());
			updateCustomerActivity.push("systemName", customerActivity.getSystemName());
			updateCustomerActivity.push("systemUrl", customerActivity.getSystemUrl());
			mongoTemplate.updateFirst(new Query(Criteria.where("Id").is(customerActivity.getId())), updateCustomerActivity, CustomerActivity.class);
		}
	}

	@Override
	public CustomerActivity getCustomerActivityById(BigInteger id) {
		return mongoTemplate.findById(id, CustomerActivity.class);
	}

	@Override
	public Collection<CustomerActivity> getAllCustomerActivities() {
		try {
			 List<CustomerActivity> allCustomers = mongoTemplate.findAll(entityClass);
			 return allCustomers;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void createCustomerActivity(String customerId, String activityDescription, Date activityTime, String activityType, String systemName, String systemUrl) {
		try {
			customerActivity.add(new CustomerActivity(customerId, activityDescription, activityTime, activityType, systemName, systemUrl));
			mongoTemplate.insert(customerActivity, entityClass);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public BigInteger findLastIdInCollection(){
		return mongoTemplate.findOne(new Query().with(new Sort(Direction.DESC,"id")), CustomerActivity.class).getId();
	}
	
	@Override
	public void deleteCustomerActivity(BigInteger customerId) {
		mongoTemplate.remove(this.getCustomerActivityById(customerId));
	}
	

	@Override
	public void createCustomerActivity(CustomerActivity newCustomer) {
		customerActivity.add(newCustomer);
		mongoTemplate.insert(customerActivity, entityClass);
	}


	@Override
	public void bulkCreateCustomerActivity(List<CustomerActivity> customerActivities) {
		for (CustomerActivity newcustomerActivity : customerActivities){
			customerActivity.add(new CustomerActivity(newcustomerActivity.getCustomerId(), newcustomerActivity.getActivityDescription(), newcustomerActivity.getActivityTime(), newcustomerActivity.getActivityType(), newcustomerActivity.getSystemName(), newcustomerActivity.getSystemUrl()));
		}
		mongoTemplate.insert(customerActivity, entityClass);
	}

	@Override
	public List<CustomerActivity> findCustomerActivityByQuery(String query) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	@Transactional
	public void deleteCustomerActivities(List<CustomerActivity> customerActivitiesToDelete) {
		for (CustomerActivity customerActivityToDelete : customerActivitiesToDelete){
			mongoTemplate.remove(new Query(Criteria.where("customerId").is(customerActivityToDelete.getCustomerId().toString())), CustomerActivity.class);
		}
	}

	@Override
	public List<CustomerActivity> getPaginatedCustomerActivities(Integer currentPage, Integer totalPerPage) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getTotalRecords() {
		return getAllCustomerActivities().size();
	}

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

	@Override
	public List<CustomerActivity> findCustomerActivityByCustomerId(String customerId) {
		return mongoTemplate.find(new Query(Criteria.where("customerId").is(new Long(customerId).toString())), CustomerActivity.class);
	}
}

Define your MongoDB Controller

package com.example.controller;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;


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

import com.example.model.CustomerActivity;
import com.example.service.CustomerActivityRepositoryImpl;

@Controller
@RequestMapping("/activity")
public class MongoController {

	@Autowired
	@Qualifier("mongoRepository")
	CustomerActivityRepositoryImpl mongoCustomerService;
 	
	@RequestMapping("")
	public String returnMongoView(Map<String, Object> map){
		map.put("mongoCustomerList", mongoCustomerService.getAllCustomerActivities());
		return "mongo";
	}
	
	@RequestMapping(value="/insert")
	public String insertCustomersView(){
		return "insertmongo";
	}
	
	@RequestMapping(value="/insert", method=RequestMethod.POST)
	public String insertCustomers(@RequestParam("customerId") String customerId, 
			@RequestParam("activityDescription") String activityDescription,
			@RequestParam("activityTime") String activityTime,
			@RequestParam("activityType") String activityType, 
			@RequestParam("systemName") String systemName,
			@RequestParam("systemUrl") String systemUrl) {
		mongoCustomerService.createCustomerActivity(customerId, activityDescription, new Date(), activityType, systemName, systemUrl);
		return "mongo";
	}
	
	@RequestMapping(value="/delete/{id}", method=RequestMethod.POST)
	public String deleteCustomer(@PathVariable("id") String id, Map<String, Object> map){
		mongoCustomerService.deleteCustomerActivity(new BigInteger(id));
		return "mongo";
	}
	
	@RequestMapping(value="/update/{id}", method=RequestMethod.GET)
	public String viewUpdateCustomer(@PathVariable("id") String id, Map<String, Object> map){
		List<CustomerActivity> customer = Arrays.asList(mongoCustomerService.getCustomerActivityById(new BigInteger(id)));
		map.put("mongoList", customer);
		return "updatemongo";
	}
	
	@RequestMapping(value="/update/{id}", method=RequestMethod.POST)
	public String updateCustomer(@PathVariable("id") String id, 
			@RequestParam("customerId") String customerId, 
			@RequestParam("activityDescription") String activityDescription,
			@RequestParam("activityType") String activityType, 
			@RequestParam("systemName") String systemName,
			@RequestParam("systemUrl") String systemUrl) {
		mongoCustomerService.updateCustomerActivity(new BigInteger(id), customerId, activityDescription, activityType, systemName,systemUrl);
		return "mongo";
	}
}

Test MongoDB DataSource

package com.example.mongo;

import static org.junit.Assert.*;

import javax.inject.Inject;
import javax.inject.Named;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

import com.example.config.MongoDataSourceConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={MongoDataSourceConfiguration.class})
public class LocalMongoConfigurationTest {

	@Inject MongoDbFactory mongoDbFactory;
	
	@Test
	public void testMongoDbFactoryConnection() {
		assertTrue(mongoDbFactory.getDb().getMongo().getConnector().isOpen());
	}
}

Test MongoDB Template

package com.example.mongo;

import static org.junit.Assert.*;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={MongoRepositoryConfiguration.class})
public class MongoTemplateTest {

	@Inject MongoTemplate mongTemplate;
	
	@Test
	public void testMongoTemplate() {
		assertEquals(mongTemplate.getCollection("lc-activity-service").getName(), "lc-activity-service");
	}
}

Test MongoDB Repository

package com.example.service;

import static org.junit.Assert.*;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.inject.Inject;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

import com.example.model.CustomerActivity;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={CustomerActivityRepositoryImpl.class})
public class CustomerActivityServiceTest {

	@Inject CustomerActivityRepository customerActivityService;
	
	@Test
	public void testCreateCustomerActivity() {
		Calendar cal = Calendar.getInstance();
		customerActivityService.createCustomerActivity("123", "Email Sent For Customer", cal.getTime(), "Email Received", "Salesforce", "http://salesforce.com/123213");
		assertNotNull(customerActivityService.findCustomerActivityByCustomerId("123"));
	}
	
	@Test
	public void testUpdateCustomerActivity(){
		List<CustomerActivity> updatecas = new ArrayList<CustomerActivity>();
		List<CustomerActivity> cas = customerActivityService.findCustomerActivityByCustomerId("123");
		for (CustomerActivity ca :cas){
			ca.setActivityDescription("SMS Sent from Customer");
			updatecas.add(ca);
		}
		customerActivityService.updateCustomerActivities(updatecas);
	}
	
	@Test
	public void deleteAllCustomerActivity(){
		customerActivityService.deleteCustomerActivity(new BigInteger("123"));
	}
	
	@Test
	public void testGetAllCustomerActivities(){
		for (CustomerActivity customerActivities : customerActivityService.getAllCustomerActivities()){
			System.out.println(customerActivities.getId() + " | " + customerActivities.getCustomerId()
			+ " | " +  customerActivities.getActivityDescription() + " | " +  customerActivities.getActivityTime()
			+ " | " + customerActivities.getActivityType() + " | " + customerActivities.getSystemName() + " | " +
			customerActivities.getSystemUrl());
		}
		assertTrue(customerActivityService.getAllCustomerActivities().size()>=0);
	}
}

Jdbc, Hibernate, Jpa, Spring Data setup with no xml

Below is a very easy way in Spring to create DataSources with no XML:

1. DataSource
1.1 Define DataSource Interface
1.2 Implement DataSource Interface
1.3 Test if DataSource is connected

2. Jdbc
2.1 Define Jdbc Configuration
2.2 Define Jdbc Service
2.3 Test Jdbc Service

3. Hibernate
3.1 Define Hibernate Configuration
3.2 Define Hibernate Service
3.3 Test Hibernate Service

4. Jpa
4.1 Define Jpa Configuration
4.2 Define Jpa Service
4.3 Test Jpa Service

5. Spring Data
5.1 Define Spring Data Configuration
5.2 Define Spring Data Service
5.3 Test Spring Data Service

1.1 Define DataSource Interface

package com.example.config;

import javax.sql.DataSource;

/**
 * handles configuring the datasource per environment
 *
 * @author Thys Michels
 */
public interface DataSourceConfiguration {
    DataSource dataSource() throws Exception;
}

1.2 Implement DataSource interface

package com.example.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.Mongo;

import javax.inject.Inject;
import javax.sql.DataSource;
import java.sql.Driver;

/**
 * @author Thys Michels
 */
@PropertySource("classpath:/services.properties")
@Configuration
@Profile("default")
public class LocalDataSourceConfiguration implements DataSourceConfiguration {

    @Inject
    private Environment environment;

    @Bean
    public DataSource dataSource() throws Exception {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setPassword(environment.getProperty("dataSource.password"));
        dataSource.setUrl(environment.getProperty("dataSource.url"));
        dataSource.setUsername(environment.getProperty("dataSource.user"));
        dataSource.setDriverClassName(environment.getPropertyAsClass("dataSource.driverClass", Driver.class).getName());
        return dataSource;
    }
}

1.3 Test if DataSource is Connected

package com.example.config;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

	public static void main(String[] args) throws SQLException {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(LocalDataSourceConfiguration.class.getPackage().getName());
        applicationContext.refresh();
        
        DataSource newDataSource =applicationContext.getBean(DataSource.class);
       
        System.out.println("DataSource Connected: " + newDataSource.getConnection().isClosed());
        newDataSource.getConnection().close();
	}
}

2. JDBC
2.1 Define jdbc Configuration

package com.example.jdbc;

import javax.inject.Inject;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:/services.properties")
@Import( { LocalDataSourceConfiguration.class })
public class JdbcConfiguration {
	
	  @Inject private DataSourceConfiguration dataSourceConfiguration;

	  @Inject private Environment environment;
	  
	  @Bean
	  public JdbcTemplate setupJdbcTemplate() throws Exception {
		 return new JdbcTemplate(dataSourceConfiguration.dataSource());
	  }
	  
	  @Bean
	  public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
	        return new DataSourceTransactionManager(dataSource);
	  }
	 
}

2.2 Define Jdbc Service

package com.example.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.example.model.Customer;
import com.example.service.CustomerService;

@Repository
@Transactional
@Qualifier("jdbcRepository")
public class JdbcCustomerService implements CustomerService{

	@Inject
    private JdbcTemplate jdbcTemplate;
	
	@Override
	public Customer updateCustomer(long id, String fn, String ln) {
		Customer updateCustomer = new Customer();
		updateCustomer.setId(id);
		updateCustomer.setFirstName(fn);
		updateCustomer.setLastName(ln);
		jdbcTemplate.update("", updateCustomer);
		return null;
	}

	@Override
	public List<Customer> updateCustomers(List<Customer> customersToUpdate) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public static final class CustomerMapper implements RowMapper<Customer>{
		@Override
		public Customer mapRow(ResultSet resultSet, int rowNum) throws SQLException {
			Customer customer = new Customer();
			customer.setId(resultSet.getLong("id"));
			customer.setFirstName(resultSet.getString("first_name"));
			customer.setLastName(resultSet.getString("last_name"));
			return customer;
		}
	}

	@Override
	public Customer getCustomerById(long id) {
		String sql = "Select * from customer where id = ?";
		return jdbcTemplate.queryForObject(sql, new Object[]{id},new CustomerMapper());
	}
}

2.3 Test Jdbc Service

package com.example.jdbc;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.example.service.CustomerService;

public class Main {

	public static void main(String[] args) {
		 	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
	        applicationContext.getEnvironment().setActiveProfiles("default");
	        applicationContext.scan(JdbcConfiguration.class.getPackage().getName());
	        applicationContext.refresh();
	        
	        CustomerService customerService = applicationContext.getBean(CustomerService.class);
	        System.out.println(customerService.getCustomerById(new Long(14)));
	}

}

3. Hibernate
3.1 Define Hibernate Configration

package com.example.hibernate;

import java.util.Properties;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.hibernate.ejb.HibernateEntityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.hibernate3.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;

@Configuration
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class HibernateConfiguration {
	
	 @Inject private DataSourceConfiguration dataSourceConfiguration;

	 @Inject private Environment environment;
	 
	 @Bean
	 public LocalSessionFactoryBean setupSessionFactory() throws Exception {
		  LocalSessionFactoryBean localSessionFactory = new LocalSessionFactoryBean();
		  localSessionFactory.setDataSource(dataSourceConfiguration.dataSource());
		  localSessionFactory.setPackagesToScan("com.example.model");
		  Properties hibernateProperties = new Properties();
		  hibernateProperties.setProperty("dialect", environment.getProperty("dataSource.dialect"));
		  localSessionFactory.setHibernateProperties(hibernateProperties);
		  return localSessionFactory;
	  }
	 
	  @Bean
	  public PlatformTransactionManager transactionManager(DataSource dataSource) throws Exception {
		  return new DataSourceTransactionManager(dataSource);
	  }
}

3.2 Define Hibernate Service

package com.example.hibernate;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.stereotype.Repository;

import com.example.model.Customer;
import com.example.service.CustomerService;

@Repository
@Qualifier("hibernateRepository")
public class HibernateCustomerService implements CustomerService{

	@Inject
	SessionFactory sessionFactory;
	
	@Override
	public Customer updateCustomer(long id, String fn, String ln) {
		Query query = sessionFactory.openSession().createQuery("update Customer set firstName=:fName, lastName=:lName where id=:id").setParameter("fName", fn).setParameter("lName", ln).setParameter("id", id);
		query.executeUpdate();
		return null;
	}

	@Override
	public Customer getCustomerById(long id) {
		return  (Customer) sessionFactory.openSession().createQuery("from Customer where id=?").setLong(0, id).list().get(0);
	}

	@Override
	public Collection<Customer> getAllCustomers() {
		return (Collection<Customer>)sessionFactory.openSession().createQuery("from Customer").list();
	}

	@Override
	public Customer createCustomer(String fn, String ln) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		Customer c = new Customer();
		c.setFirstName(fn);
		c.setLastName(ln);
		session.save(c);
		tx.commit();
		session.close();
		return c;
	}

	@Override
	public void deleteCustomer(long id) {
		Query query = sessionFactory.openSession().createQuery("delete Customer where id = :id").setParameter("id", id);
		query.executeUpdate();
	}

	@Override
	public Customer createCustomer(Customer newCustomer) {
		Session session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(newCustomer);
		tx.commit();
		session.close();
		return newCustomer;
	}

	@Override
	public int getTotalRecords() {
		String hql = "Select count(*) from Customer";
		Query query = sessionFactory.openSession().createQuery(hql);
		return ((Long)query.uniqueResult()).intValue();
	}
}

3.3 Test Hibernate Service

package com.example.hibernate;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.example.service.CustomerService;

public class Main {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(HibernateConfiguration.class.getPackage().getName());
        applicationContext.refresh();
        
        CustomerService customerService = applicationContext.getBean(CustomerService.class);
        System.out.println(customerService.getAllCustomers());
        System.out.println(customerService.getCustomerById(new Long(14)));
        System.out.println(customerService.createCustomer("HibernateFName", "HibernateLName"));
        customerService.deleteCustomer(new Long(226));
        customerService.updateCustomer(new Long(225), "PName", "PLastName");
	}
}

4. Jpa
4.1 Define Jpa Configuration

package com.example.jpa;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;
import com.example.model.Customer;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;


@Configuration
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class JpaConfiguration {

    @Inject private DataSourceConfiguration dataSourceConfiguration;

    @Inject private Environment environment;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource());
        localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName());

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);

        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
        return new JpaTransactionManager(entityManagerFactory);
    }   
}

4.2 Define Jpa Service

package com.example.jpa;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.service.CustomerService;
import com.example.model.Customer;

@Repository
@Qualifier("jpaRepository")
@Transactional(readOnly = true)
public class JpaCustomerService implements CustomerService {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly = true)
    public Customer getCustomerById(long id) {
        return this.entityManager.find(Customer.class, id);
    }

    public Customer createCustomer(String fn, String ln) {
        Customer newCustomer = new Customer();
        newCustomer.setFirstName(fn);
        newCustomer.setLastName(ln);
        this.entityManager.persist(newCustomer);
        return newCustomer;
    }
    
    @Transactional
    public Customer updateCustomer(long id, String fn, String ln) {
        Customer customer = this.getCustomerById(id);
        customer.setFirstName(fn);
        customer.setLastName(ln);
        this.entityManager.merge(customer);
        return getCustomerById(id);
    }

	public Collection<Customer> getAllCustomers() {
		 CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
	        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
	        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
	                criteriaBuilderQuery.from(Customer.class));
	        return this.entityManager.createQuery(customerCriteriaQuery).getResultList();
	}

	@Transactional
	public void deleteCustomer(long id) {
		Customer customerToDelete = this.entityManager.find(Customer.class, id);
		this.entityManager.remove(customerToDelete);
	}

	public Customer createCustomer(Customer newCustomer) {
		 this.entityManager.persist(newCustomer);
	     return newCustomer;
	}

	@Transactional
	public Customer updateCustomer(long id, Customer updateCustomer) {
		Customer customer = this.getCustomerById(id);
		customer.setFirstName(updateCustomer.getFirstName());
	    customer.setLastName(updateCustomer.getLastName());
		this.entityManager.merge(customer);
        return getCustomerById(id);
	}

	@Override
	public List<Customer> bulkCreate(List<Customer> customers) {
		for (Customer customer : customers){
			this.entityManager.persist(customer);
		}
		return customers;
	}

	@Override
	public List<Customer> findCustomerByQuery(String query) {
		return this.entityManager.createNativeQuery(query, Customer.class).getResultList();
	}

	@Transactional
	public void deleteCustomers(List<Customer> customersToDelete) {
		for (Customer customer : customersToDelete){
			entityManager.remove(customer);
		}
	}

	@Override
	public List<Customer> getPaginatedCustomer(Integer currentPage,
			Integer totalPerPage) {
		CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
                criteriaBuilderQuery.from(Customer.class));
        return this.entityManager.createQuery(customerCriteriaQuery).getResultList().subList(currentPage, totalPerPage);
	}

	@Transactional
	public List<Customer> updateCustomers(List<Customer> customersToUpdate) {
		List<Customer> listOfUpdatedCustomers = new ArrayList<Customer>();
		for (Customer customerToUpdate : customersToUpdate){
		 this.entityManager.merge(customerToUpdate);
		 listOfUpdatedCustomers.add(getCustomerById(customerToUpdate.getId()));
		}
		return listOfUpdatedCustomers;
	}

	@Override
	public int getTotalRecords() {
		CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
        CriteriaQuery<Customer> criteriaBuilderQuery = criteriaBuilder.createQuery(Customer.class);
        CriteriaQuery<Customer> customerCriteriaQuery = criteriaBuilderQuery.select(
                criteriaBuilderQuery.from(Customer.class));
        return this.entityManager.createQuery(customerCriteriaQuery).getResultList().size();
	}

	@Override
	public List<String> getPaginationSequence() {
		List<String> listOfPages = new ArrayList<String>();
		for (int k = 1; k < (int)Math.round((this.getTotalRecords()/10)+0.5)+1; k++){
			listOfPages.add(String.valueOf(k));
		}
		return listOfPages;
	}

	@Override
	public void createCustomersFromMap(Map<String, String> mapOfCustomers) {
		for (Map.Entry<String, String> customer : mapOfCustomers.entrySet()){
			Customer newCustomer = new Customer();
			newCustomer.setFirstName(customer.getKey());
			newCustomer.setLastName(customer.getValue());
			createCustomer(newCustomer);
		}
	}	
}

4.3 Test Jpa Service

package com.example.jpa;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.service.CustomerService;
import com.example.model.Customer;


public class Main {
    public static void main(String args[]) throws Throwable {

        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.getEnvironment().setActiveProfiles("default");
        applicationContext.scan(JpaConfiguration.class.getPackage().getName());
        applicationContext.refresh();

        Log log = LogFactory.getLog(Main.class);

        CustomerService customerService = applicationContext.getBean(CustomerService.class);

        Customer customer = customerService.createCustomer("Test", "Jpa");

        Customer retrievedCustomer = customerService.getCustomerById(customer.getId());

        log.info(String.format("customer.id (%s) == retreivedCustomer.id (%s)?  %s",
                customer.getId(), retrievedCustomer.getId(), customer.getId().equals(retrievedCustomer.getId())));

        Customer updatedCustomer = customerService.updateCustomer(customer.getId(), "JPA", "Lover");
        log.info(String.format("updated customer's firstName: %s", updatedCustomer.getFirstName()));
        
        Collection<Customer> listOfCustomers = customerService.getAllCustomers();
        for (Customer c : listOfCustomers){
        	System.out.println(c);
        }
        
        List<Customer> createDummyCustomers = new ArrayList<Customer>();
        for (int k = 0; k < 10; k++){
        	Customer dummy = new Customer();
        	dummy.setFirstName("FName"+k);
        	dummy.setLastName("LName"+k);
        	createDummyCustomers.add(dummy);
        }
        
        List<Customer> insertedCustomer = customerService.bulkCreate(createDummyCustomers);
        for (Customer c : insertedCustomer){
        	System.out.println(c);
        }
        
        
        List<Customer> customQueryCustomer = customerService.findCustomerByQuery("Select * from customer");
        for (Customer c : customQueryCustomer){
        	System.out.println(c);
        }
        
        List<Customer> customerPagination = customerService.getPaginatedCustomer(0, 10);
        for (Customer c : customerPagination){
        	System.out.println(c);
        }
       
        System.out.println((int)Math.round((customerService.getTotalRecords()/10)+0.5));
        System.out.println(customerService.getPaginationSequence());
    }
}

5. Spring Data
5.1 Configure Spring Data

package com.example.spring_data;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.example.config.DataSourceConfiguration;
import com.example.config.LocalDataSourceConfiguration;
import com.example.model.Customer;

import javax.inject.Inject;
import javax.persistence.EntityManagerFactory;


@Configuration
@EnableJpaRepositories
@PropertySource("classpath:/services.properties")
@EnableTransactionManagement
@Import( { LocalDataSourceConfiguration.class })
public class JpaCustomerConfiguration {

    @Inject private DataSourceConfiguration dataSourceConfiguration;

    @Inject private Environment environment;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {

        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        localContainerEntityManagerFactoryBean.setDataSource(dataSourceConfiguration.dataSource());
        localContainerEntityManagerFactoryBean.setPackagesToScan(Customer.class.getPackage().getName());

        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(true);

        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
        
        return localContainerEntityManagerFactoryBean;
    }

    @Bean
    public PlatformTransactionManager transactionManager() throws Exception {
        EntityManagerFactory entityManagerFactory = entityManagerFactory().getObject();
        return new JpaTransactionManager(entityManagerFactory);
    }   
}

5.2 Define Spring Data Service

package com.example.spring_data;

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.CrudRepository;

import com.example.model.Customer;

@EnableJpaRepositories
public interface CustomerCRUDRepository extends CrudRepository<Customer, Long>, QueryDslPredicateExecutor<Customer>{
}

5.3 Test Spring Data Service

package com.example.spring_data;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.example.model.Customer;

public class Main {
	
	public static void main(String[] args) {
		 	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
	        applicationContext.getEnvironment().setActiveProfiles("default");
	        applicationContext.scan(JpaCustomerConfiguration.class.getPackage().getName());
	        applicationContext.refresh();

	        CustomerCRUDRepository cr = applicationContext.getBean(CustomerCRUDRepository.class);
	        System.out.println(cr.count());
	        //cr.delete(new Long(224));
	        Customer newCustomer = new Customer("DataJpaFName", "DataJpaLName");
	        cr.save(newCustomer);
	        System.out.println(cr.findAll());
	        System.out.println(cr.exists(new Long(224)));
	        System.out.println(cr.findOne(new Long(14)));
	}
}

All code can be found here:
https://github.com/thysmichels/cloudsole-database