The DAO with JPA and Spring

1. Overview

This article will show how to implement the DAO with Spring and JPA. For the core JPA configuration, see the article about JPA with Spring.

2. No More Spring Templates

Starting with Spring 3.1, the JpaTemplate and the corresponding JpaDaoSupport have been deprecated in favor of using the native Java Persistence API.

Also, both of these classes are only relevant for JPA 1 (from the JpaTemplate javadoc):

Note that this class did not get upgraded to JPA 2.0 and never will.

As a consequence, it is now best practice to use the Java Persistence API directly instead of the JpaTemplate.

2.1. Exception Translation without the Template

One of the responsibilities of JpaTemplate was exception translation – translating the low level exceptions into higher level, generic Spring exceptions.

Without the template, exception translation is still enabled and fully functional for all DAOs annotated with @Repository. Spring implements this with a bean postprocessor which will advice all @Repository beans with all the PersistenceExceptionTranslator found in the Container.

It is also important to note that the exception translation mechanism uses proxies – in order for Spring to be able to create proxies around the DAO classes, these must not be declared final.

3. The DAO

First, we’ll implement the base layer for all the DAOs – an abstract class using generics and designed to be extended:

public abstract class AbstractJpaDAO< T extends Serializable > {

   private Class< T > clazz;

   @PersistenceContext
   EntityManager entityManager;

   public final void setClazz( Class< T > clazzToSet ){
      this.clazz = clazzToSet;
   }

   public T findOne( long id ){
      return entityManager.find( clazz, id );
   }
   public List< T > findAll(){
      return entityManager.createQuery( "from " + clazz.getName() )
       .getResultList();
   }

   public void create( T entity ){
      entityManager.persist( entity );
   }

   public T update( T entity ){
      return entityManager.merge( entity );
   }

   public void delete( T entity ){
      entityManager.remove( entity );
   }
   public void deleteById( long entityId ){
      T entity = findOne( entityId );
      delete( entity );
   }
}

The main interesting aspect here is the way the EntityManager is injected – using the standard @PersistenceContext annotation. Under the hood, this is handled by the PersistenceAnnotationBeanPostProcessor – which processes the annotation, retrieves the JPA entity manager from the contains and injects it.

The persistence post processor is either created explicitly by defining it in the configuration, or automatically, by defining context:annotation-config or context:component-scan in the namespace config.

Also, note that the entity Class is passed in the constructor to be used in the generic operations:

@Repository
public class FooDAO extends AbstractJPADAO< Foo > implements IFooDAO{

   public FooDAO(){
      setClazz(Foo.class );
   }
}

4. Conclusion

This tutorial illustrated how to set up a DAO layer with Spring and JPA, using both XML and Java based configuration. We also discussed why not to use the JpaTemplate and how to replace it with the EntityManager. The final result is a lightweight, clean DAO implementation, with almost no compile-time reliance on Spring.

The implementation of this simple project can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Persistence on Google+ - you can follow me there:

>> GET THE EBOOKS <<
Get the eBooks and Learn to Build a Simple App
×
Build a Simple but Working App with Spring

, ,

  • http://blog.stepniak.net.pl/ Szymon Stepniak

    I’m wondering if adding abstract method like:

    public abstract Class getGenericClass();

    and replacing use of clazz property with it, wouldn’t be better than consist in subclass will set correct class type in its constructor. It would be also NPE-safe.

    Good article anyway, best regards,
    Szymon