Spring Jpa different object already associated

ERROR: A different object with the same identifier value was already associated with the session

Solution: See if an existing ID already exist, if not persist record. If same ID found, merge with existing record

@Override
	@Transactional(value="dwTransactionManager", propagation=Propagation.REQUIRES_NEW)
	public void insertLog(Error[] errorRecords, Long recordId, String salesforceId, String objectName) {
		for (Error errorRecord : errorRecords){
			try {
				DWLog log = new DWLog();
				log.setId(new BigDecimal(recordId));
				Calendar cal = Calendar.getInstance();
				log.setLastSyncD(cal.getTime());
				log.setLastSyncMsg("ERROR CODE: " + errorRecord.getStatusCode() + " MESSAGE: " + errorRecord.getMessage());
				log.setObjectSync(objectName);
				if (entityManager.find(DWLog.class,log.Id)!=null){
					entityManager.merge(log);	
				}else{
					entityManager.persist(log);	
				}
			} catch (Exception e) {
				logger.error("LogDaoImpl.insertLog(): " + e.getMessage());
			}
		}
	}

Spring JPA Embeddable Id example

Embeddable Entity

package com.sforce.model;

import java.io.Serializable;
import javax.persistence.*;

@Embeddable
public class MonthlyPK implements Serializable {
	
	private static final long serialVersionUID = 1L;

	@Column(name="AID")
	private long aid;

	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="N_DATE")
	private java.util.Date nDate;

	public MonthlyPK() {
	}
	public long getAid() {
		return this.aid;
	}
	public void setAid(long aid) {
		this.aid = aid;
	}
	public java.util.Date getNDate() {
		return this.nDate;
	}
	public void setNDate(java.util.Date nDate) {
		this.nDate = nDate;
	}

	public boolean equals(Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof MonthlyPK)) {
			return false;
		}
		MonthlyPK castOther = (MonthlyPK)other;
		return 
			(this.aid == castOther.aid)
			&& this.nDate.equals(castOther.nDate);
	}

	public int hashCode() {
		final int prime = 31;
		int hash = 17;
		hash = hash * prime + ((int) (this.aid ^ (this.aid >>> 32)));
		hash = hash * prime + this.nDate.hashCode();
		
		return hash;
	}
}

Embeddable Id as @Id

package com.sforce.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import java.io.Serializable;

import java.math.BigDecimal;
import java.util.Date;

@Entity 
@Table(name="DEV$MONTHLY")
public class DevMonthly implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	private MonthlyNarPK monthlyNarPK;
	
	@Column(name="AID", insertable=false, updatable=false)
	private Long id;

	@Column(name="CHNG_STATUS")
	private BigDecimal chngStatus;

	@Column(name="NAR")
	private BigDecimal nar;

	@Column(name="SF_AMID")
	private String sfAmid;
	
	@Temporal(TemporalType.TIMESTAMP)
	@Column(name="NAR_DATE", insertable=false, updatable=false)
	private Date narDate;

	public DevMonthly() {}
	
	public DevMonthly(String sfAmid){
		this.sfAmid = sfAmid;
	}
	
	public DevMonthly(Long id, String sfAmid, Date narDate) {
		this.id = id;
		this.sfAmid = sfAmid;
		this.narDate = narDate;
	}

	public Long getId() {
		return this.id;
	}

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

	public BigDecimal getChngStatus() {
		return this.chngStatus;
	}

	public void setChngStatus(BigDecimal chngStatus) {
		this.chngStatus = chngStatus;
	}

	public BigDecimal getNar() {
		return this.nar;
	}

	public void setNar(BigDecimal nar) {
		this.nar = nar;
	}

	public String getSfAmid() {
		return this.sfAmid;
	}

	public void setSfAmid(String sfAmid) {
		this.sfAmid = sfAmid;
	}

	public Date getNarDate() {
		return narDate;
	}

	public void setNarDate(Date narDate) {
		this.narDate = narDate;
	}
}

Spring JPA No qualifying bean of type: javax.persistence.EntityManagerFactory

You can define two EntityManagers in one class:
1. Provide a name for your EntityManager Beans
2. Provide a persistentUnitName and make sure it is unique.

As the entityManager injects by name into the transaction manager make sure you entitymanager bean name is same as your transaction manager parameter. In this case my entitytManager bean name is “dwEntityManager” and my transactionmanager has the same name: javax.persistence.EntityManagerFactory dwEntityManager

package com.sforce.jpa;

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

import org.slf4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.sforce.model.DWAccount;
import com.smallbusiness.model.DWBusiness;

@PropertySource("classpath:salesforcesync.properties")
@Configuration
@EnableTransactionManagement
public class JpaConfigurationImpl {
	
	 private static final Logger logger = org.slf4j.LoggerFactory.getLogger(JpaConfigurationImpl.class);
	
	 @Inject @Named("lcDwDataSource") DataSource lcDwDataSource;
	 @Inject @Named("lcDataSource") DataSource lcDataSource;
	 
	 @Inject private Environment environment;
	
	 @Bean(name="dwEntityManager")
	 public LocalContainerEntityManagerFactoryBean dwEntityManagerFactory() {
		 try {
			  LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
		      localContainerEntityManagerFactoryBean.setDataSource(lcDwDataSource);
		      localContainerEntityManagerFactoryBean.setPackagesToScan(DWAccount.class.getPackage().getName());
		      localContainerEntityManagerFactoryBean.setPersistenceUnitName("dw");
		      HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
		      
		      jpaVendorAdapter.setGenerateDdl(false);
		      jpaVendorAdapter.setShowSql(true);
		      jpaVendorAdapter.setDatabasePlatform(environment.getProperty("dataSource.dialect"));
		      localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
		      return localContainerEntityManagerFactoryBean;
		      
		 } catch (Exception e) {
			logger.error("JpaConfigurationImpl.entityManagerFactory(): " + e.getMessage());
		 }
		 return new LocalContainerEntityManagerFactoryBean();
	 }
	 
	 @Bean(name="dwTransactionManager")
	 public PlatformTransactionManager dwTransactionManager(javax.persistence.EntityManagerFactory dwEntityManager) {
		try {
			return new JpaTransactionManager(dwEntityManager);
		} catch (Exception e) {
			logger.error("JpaConfigurationImpl.transactionManager(): " + e.getMessage());
		}
		return new JpaTransactionManager();
	 }
	 
	 @Bean(name="lcEntityManager")
	 public LocalContainerEntityManagerFactoryBean sbEntityManagerFactory() {
		 try {
			  LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
		      localContainerEntityManagerFactoryBean.setDataSource(lcDataSource);
		      localContainerEntityManagerFactoryBean.setPackagesToScan(DWBusiness.class.getPackage().getName());
		      localContainerEntityManagerFactoryBean.setPersistenceUnitName("lc");
		      HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
		      
		      jpaVendorAdapter.setGenerateDdl(false);
		      jpaVendorAdapter.setShowSql(true);
		      jpaVendorAdapter.setDatabasePlatform(environment.getProperty("dataSource.dialect"));
		      localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
		      return localContainerEntityManagerFactoryBean;
		      
		 } catch (Exception e) {
			logger.error("JpaConfigurationImpl.entityManagerFactory(): " + e.getMessage());
		 }
		 return new LocalContainerEntityManagerFactoryBean();
	 }
	 
	 @Bean(name="lcTransactionManager")
	 public PlatformTransactionManager sbTransactionManager(javax.persistence.EntityManagerFactory lcEntityManager) {
		try {
			return new JpaTransactionManager(lcEntityManager);
		} catch (Exception e) {
			logger.error("JpaConfigurationImpl.transactionManager(): " + e.getMessage());
		}
		return new JpaTransactionManager();
	 }
}

Now that we have the two entityManagers defined we can call them respectively by specifying the unitName for each entityManager:

@PersistenceContext(unitName="dw")
private EntityManager dwEntityManager;

@PersistenceContext(unitName="lc")
private EntityManager lcEntityManager;

JPA Criteria Query Examples

Get All Accounts

@Override
public Collection<DWAccount> getListAccount() {
          CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
	   CriteriaQuery<DWAccount> criteriaBuilderQuery = criteriaBuilder.createQuery(DWAccount.class);
	   CriteriaQuery<DWAccount> accountCriteriaQuery = criteriaBuilderQuery.select(criteriaBuilderQuery.from(DWAccount.class));
	   return this.entityManager.createQuery(accountCriteriaQuery).setMaxResults(200).getResultList();
	}

Select * from Account where SSN=?

@Override
public DWAccount findAccountBySSN(DWAccount accountWithMatchingSSN) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
	    CriteriaQuery<DWAccount> criteriaQuery = criteriaBuilder.createQuery(DWAccount.class);
	    Root<DWAccount> root = criteriaQuery.from(DWAccount.class);
	    criteriaQuery.select(root);
	    criteriaQuery.where(criteriaBuilder.equal(root.get("ssn"), accountWithMatchingSSN.getSsn()));
	    List<DWAccount> retrievedMatchedSSNAccounts = this.entityManager.createQuery(criteriaQuery).getResultList();
	    if (!retrievedMatchedSSNAccounts.isEmpty())
	    	return retrievedMatchedSSNAccounts.get(0);
	    else
	    	return null;
}

Select * from DWLoan where aid=? and chngStatus is not null

	@Override
	@Transactional
	public void findAndUpdateLoanByAccountId(Map<DWAccount, UpsertResult> accountsLoadedResult) {
		for (DWAccount dwAccounts : accountsLoadedResult.keySet()){
			CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
			CriteriaQuery<DWLoan> criteriaQuery = criteriaBuilder.createQuery(DWLoan.class);
			Root<DWLoan> root = criteriaQuery.from(DWLoan.class);
			Predicate p = criteriaBuilder.conjunction();
			p = criteriaBuilder.and(criteriaBuilder.equal(root.get("aid"), dwAccounts.getId()), criteriaBuilder.isNotNull(root.get("chngStatus")));
			criteriaQuery.select(root);
			criteriaQuery.where(p);
			for (DWLoan dwLoan : this.entityManager.createQuery(criteriaQuery).getResultList()){
				dwLoan.setSfAmid(accountsLoadedResult.get(dwAccounts).getId());
				this.entityManager.merge(dwLoan);
			}
		}
	}

Count number of rows in Account Table

@Override
public int getAccountTotal() {
		Number result = (Number) this.entityManager.createNativeQuery("Select count(id) from DW$SF$ACCOUNT").getSingleResult();
		return result.intValue();
}

SELECT id,status,created_at from transactions where status=’1′ and currency=’USD’ and appId=’123′ order by id

Map<String, Object> params = ...;
CriteriaBuilder cb = em.getCriteriaBuilder();           
CriteriaQuery<Tuple> cq = cb.createTupleQuery();     
Root<Transaction> r = cq.from(Transaction.class);

Predicate p= cb.conjunction();
for (Map.Entry<String, Object> param: params.entrySet())
    p = cb.and(p, cb.equal(r.get(param.getKey()), param.getValue()));

cq.multiselect(r.get("id"), r.get("status"), r.get("created_at"))
    .where(p)
    .orderBy(cb.asc(r.get("id")));

List<Tuple> result = em.createQuery(cq).getResultList();

Spring Jpa Transaction Manager Junit Testing

Setup Jpa Transaction Manager

package com.sforce.jpa;

import javax.inject.Inject;
import javax.inject.Named;
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.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.sforce.datasource.DataSourceConfigImpl;
import com.sforce.model.DWAccount;

@PropertySource("classpath:/salesforcesync.properties")
@Configuration
@EnableTransactionManagement
@Import( { DataSourceConfigImpl.class })
public class JpaConfigurationImpl {
	
	 @Inject private Environment environment;
	 @Inject @Named("testDwDataSource") private DataSource testDwDataSource;
		
	 @Bean
	 public LocalContainerEntityManagerFactoryBean entityManagerFactory() throws Exception {
	        LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
	        localContainerEntityManagerFactoryBean.setDataSource(testDwDataSource);
	        localContainerEntityManagerFactoryBean.setPackagesToScan(DWAccount.class.getPackage().getName());
	       
	        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
	        jpaVendorAdapter.setGenerateDdl(false);
	        jpaVendorAdapter.setShowSql(true);
	        jpaVendorAdapter.setDatabasePlatform(environment.getProperty("dataSource.dialect"));
	        
	        localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
	        return localContainerEntityManagerFactoryBean;
	    }
	 
	 @Bean
	 public PlatformTransactionManager transactionManager() throws Exception {
		 JpaTransactionManager transactionManager = new JpaTransactionManager();
	     transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
	     return transactionManager;
	 }
}

Test Jpa Transaction Manager

package com.sforce.jpa;

import static org.junit.Assert.*;

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


import org.junit.Ignore;
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.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
@Transactional
@ContextConfiguration(classes={JpaConfigurationImpl.class})
public class JpaTransactionConfigTest {

	@PersistenceContext
        EntityManager entityManager;
	
	@Test
	public void testDWAccountInsert() {
		DWAccount newDWAccount = new DWAccount();
		newDWAccount.setId(new Long(1234));
		entityManager.persist(newDWAccount);
                assertNotNull(entityManager.find(DWAccount.class, new Long(1234));
	}
}

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