Implementing persistence layer may need some effort to configure and develop some DAO classes.

Spring-Data-JPA framework can simplify the creation of JPA based repositories and to reduce the amount of code needed to communicate with a database


Photo credit Ivan Kmit

This post is an introduction to Spring-Data-JPA. It describes, how you can configure the framewok when you are using Hibernate as your JPA provider.
In this post I will take profit from some Spring 4 new feature as generics autowiring to create generic service.
You can get the sample project from this link to start using Spring-Data-jpa and try some more advenced features.

1- Project dependencies

Spring-Data-JPA references a Spring 3 version. Maven will resolve dependencies by using Spring 3 version instead of version 4.

We need to exclude spring-core and spring-context and import Spring 4 version.

   <!-- Spring -->

2- Add an Entity

@Table(name = "users")
public class User {

    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    @Column(name = "id", nullable = false)
    private Long id;

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

    /* Add some extra attributes */     

    /* Add getters and setters */


3- Create repository

Declare an interface extending Repository.

import com.mycompany.myproject.persist.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepo extends JpaRepository<User, Long> {

    User findByLogin(String login);


Spring-Data-JPA analyses the method name and generates a query using the JPA criteria.
Query generation is base on key words like (And, Or, Is, Equals, Between …). For more details, you can read the official Spring-Data-JPA documentation in this link.

4- Create Service

We make a choice to create a generic service that will reference the repository created in previous step.

One of the new features of Spring4 is generic types qualifier. We will take profit from this feature to inject repository by its generic interface.

public class GenericServiceImpl<T, D, ID extends Serializable> implements GenericService<T, D, ID> {

    private JpaRepository<T, ID> repository;

    private DozerBeanMapper mapper;

    protected Class<T> entityClass;

    protected Class<D> dtoClass;

    public GenericServiceImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
        this.dtoClass = (Class<D>) genericSuperclass.getActualTypeArguments()[1];

    public D findOne(ID id) {
        return mapper.map(repository.findOne(id), dtoClass);

    public List<D> findAll() {
        List<D> result = new ArrayList<D>();
        for (T t : repository.findAll()) {
            result.add(mapper.map(t, dtoClass));
        return result;
    public void save(D dto) {
        repository.saveAndFlush(mapper.map(dto, entityClass));


Next, we add UserService that extends GenericServcie.

public class UserServiceImpl extends GenericServiceImpl<User, UserDto, Long> {

5- Configure the project

  • line 15 : EnableJpaRepositories annotation enables scanning package to look for repository interfaces (created in staep 3).
  • line 21 : We use HSQL embedded database. We need to provide schema script and data script.

import javax.sql.DataSource;
import org.dozer.DozerBeanMapper;
import org.springframework.context.annotation.*;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.embedded.*;
import org.springframework.orm.jpa.*;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@ComponentScan({"com.mycompany.myproject.persist", "com.mycompany.myproject.service"})
public class JPAConfig {

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).setName("myDb")

    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setPackagesToScan(new String[] { "com.mycompany.myproject.persist" });
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        return factoryBean;

    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        return transactionManager;

    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();

    public DozerBeanMapper getMapper() {
        return new DozerBeanMapper();

6- Test your application

@ContextConfiguration(classes = {JPAConfig.class })
public class GenericServiceTest {
	private GenericService<User, UserDto, Long> userService;
    private GenericService<Authority, AuthorityDto, Long> authorityService;
	public void testFindOneUser() {
		UserDto userDto = userService.findOne(1L);
		Assert.assertEquals(1, userDto.getId().longValue());
    public void testFindOneAuthority() {
        AuthorityDto authorityDto = authorityService.findOne(1L);
        Assert.assertEquals(1, authorityDto.getId().longValue());
    public void testFindAll() {
        List<AuthorityDto> authorities = authorityService.findAll();
    public void testSave() {
        AuthorityDto authorityDto = new AuthorityDto();
        authorityDto.setName("test authority");

If you are a concise code adept you will appreciate using Spring-Data-JPA. To get your repositories you just need to add some interfaces for entities. You don’t need to write redundant basic code for each persistent bean.

The mix of Spring-DATA-JPA and Spring4 gives some extra possibilities to write generic code for the persistence layer.