The Price of all “Learn Spring Security” course packages will permanently increase by $50 on the 8th of December:

>>> GET ACCESS NOW

Table of Contents

1. Overview

This article will focus on simplifying the DAO layer by using a single, generified Data Access Object for all entities in the system, which will result in elegant data access, with no unnecessary clutter or verbosity.

2. The Hibernate and JPA DAOs

Most production codebases have some kind of DAO layer. Usually, the implementation ranges from multiple classes with no abstract base class to some kind of generified class. However, one thing is consistent – there is always more than one – most likely, there is a one to one relation between the DAOs and the entities in the system.

Also, depending on the level of generics involved, the actual implementations can vary from heavily duplicated code to almost empty, with the bulk of the logic grouped in a base abstract class.

These multiple implementations can usually be replaced by a single parametrized DAO used in such no functionality is lost by taking full advantage of the type safety provided by Java Generics.

Two implementations of this concept are presented next, one for a Hibernate centric persistence layer and the other focusing on JPA. These implementations are by no means complete – only some data access methods are included, but they can be easily be made more thorough.

2.1. The Abstract Hibernate DAO

public abstract class AbstractHibernateDao< T extends Serializable > {

   private Class< T > clazz;

   @Autowired
   SessionFactory sessionFactory;

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

   public T findOne( long id ){
      return (T) getCurrentSession().get( clazz, id );
   }
   public List< T > findAll(){
      return getCurrentSession().createQuery( "from " + clazz.getName() ).list();
   }

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

   public void update( T entity ){
      getCurrentSession().merge( entity );
   }

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

   protected final Session getCurrentSession() {
      return sessionFactory.getCurrentSession();
   }
}

The DAO uses the Hibernate API directly, without relying on any Spring templates (such as HibernateTemplate). Using of templates, as well as management of the SessionFactory which is autowired in the DAO were covered in the Hibernate DAO tutorial.

2.2. The Generic Hibernate DAO

Now that the abstract DAO is done, we can implement it just once – the generic DAO implementation will become the only implementation needed:

@Repository
@Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericHibernateDao< T extends Serializable >
  extends AbstractHibernateDao< T > implements IGenericDao< T >{
   //
}

First, note that the generic implementation is itself parameterized – allowing the client to choose the correct parameter in a case by case basis. This will mean that the clients get all the benefits of type safety without needing to create multiple artifacts for each entity.

Second, notice the prototype scope of this generic DAO implementation. Using this scope means that the Spring container will create a new instance of the DAO each time it is requested (including on autowiring). That will allow a service to use multiple DAOs with different parameters for different entities, as needed.

The reason this scope is so important is due to the way Spring initializes beans in the container. Leaving the generic DAO without a scope would mean using the default singleton scope, which would lead to a single instance of the DAO living in the container. That would obviously be majorly restrictive for any kind of more complex scenario.

The IGenericDao is simply an interface for all the DAO methods so that we can inject our implementation with Spring in (or in whatever is needed):

public interface IGenericDao<T extends Serializable> {

   T findOne(final long id);

   List<T> findAll();

   void create(final T entity);

   T update(final T entity);

   void delete(final T entity);

   void deleteById(final long entityId);
}

2.3. The Abstract JPA DAO

public abstract class AbstractJpaDao< T extends Serializable > {

   private Class< T > clazz;

   @PersistenceContext
   EntityManager entityManager;

   public 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 save( T entity ){
      entityManager.persist( entity );
   }

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

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

Similar to the Hibernate DAO implementation, the Java Persistence API is used here directly, again not relying on the now deprecated Spring JpaTemplate.

2.4. The Generic JPA DAO

Similar to the Hibernate implementation, the JPA Data Access Object is straightforward as well:

@Repository
@Scope( BeanDefinition.SCOPE_PROTOTYPE )
public class GenericJpaDao< T extends Serializable >
 extends AbstractJpaDao< T > implements IGenericDao< T >{
   //
}

3. Injecting this DAO

There is now a single DAO to be injected by Spring; also, the Class needs to be specified:

@Service
class FooService implements IFooService{

   IGenericDao< Foo > dao;

   @Autowired
   public void setDao( IGenericDao< Foo > daoToSet ){
      dao = daoToSet;
      dao.setClazz( Foo.class );
   }

   // ...
27*6
}

Spring autowires the new DAO instance using setter injection so that the implementation can be customized with the Class object. After this point, the DAO is fully parametrized and ready to be used by the service.

There are of course other ways that the class can be specified for the DAO – via reflection, or even in XML. My preference is towards this simpler solution because of the improved readability and transparency compared to using reflection.

4. Conclusion

This article discussed the simplification of the Data Access Layer by providing a single, reusable implementation of a generic DAO. This implementation was presented in both a Hibernate and a JPA based environment. The result is a streamlined persistence layer, with no unnecessary clutter.

For a step by step introduction about setting up the Spring context using Java based configuration and the basic Maven pom for the project, see this article.

The Price of all “Learn Spring Security” course packages will permanently increase by $50 on the 8th of December:

>>> GET ACCESS NOW

Sort by:   newest | oldest | most voted
Timo Westkämper
Guest

You might want to consider using Spring Data instead. It provides a neat DAO/Repository abstraction layer for multiple backends, including JPA.

Eugen Paraschiv
Guest

I wrote a similar article about Spring Data as well: http://www.baeldung.com/2011/12/22/the-persistence-layer-with-spring-data-jpa/

Dimitris
Guest

Nice introduction to the generic repository pattern. However the proposed prototype scope is a bad idea IMHO. Instead define concrete subclasses that encapsulate the necessary configuration. e.g.:

@Repository
public class CustomerDAO extends AbstractJpaDAO {

public CustomerDAO() {
setClazz(Customer.class );
}
}

This is more semantically correct code. It also safer; a “client” cannot forget to initialize it properly. Moreover it provides a dedicated space for “customer” specific operations, works wonders for IDEs (searching, refactoring, etc.) and keeps your server memory consumption at minimum by using only a single instance.

Eugen Paraschiv
Guest
Well, this is the standard approach and it has advantages and disadvantages – for one, and this is important, you would have a lot of code duplication – lots of classes essentially doing nothing special – this has costs and is overly verbose, one of the major problems in Java. Also, for a large codebase, you could potentially end up with hundreds of these classes (multiplied by two assuming you’re using an interface for each one as well). The prototype scope may mean a few more objects, but really, these are extremely lightweight (stateless) so it’s very unlikely that this… Read more »
LG Optimusv
Guest

“which would lead to a single instance of the DAO living in the container. That would obviously be majorly restrictive for any kind of more complex scenario.”: I would like to see a complex case where a prototype-scoped DAO is better than a singleton-scoped DAO. I think the only case a prototype-scoped DAO is needed is that that DAO stores some states (i.e. it has member variables), but then why does a DAO need to store states?

Eugen Paraschiv
Guest

I was thinking of the instance of a Class which is helpful when writing some queries. That would be the only state that requires the prototype scope; if that’s not the case (and if using things like spring-data it’s not in all likelihood necessary) then the prototype scope is not necessary and we can just inject the simple generic dao with different generic parameters and let erasures do the rest.
Thanks for pointing it out – I’ll update the article accordingly.
Eugen.

Victor
Guest

I totally agree with Dimitris on this one. Having the concrete subclass really helps with the readability and clarity of the code. IMO, a better clarity is to e chosen, even if you might end up with some concrete subclasses that have few specific operations.

Eugen Paraschiv
Guest
I do agree that in some cases, having a concrete class for each entity would make sense. Let’s look however at the advantages mentioned: – dedicated customer operations – the operations are not dedicated, and that’s the whole point; in fact the operations are standard, there’s nothing special about getting all of Foo or getting all of Bar; Spring data does the same – it provides the common operations in a common interface you extend, just because the is nothing specific about the operations – IDE support – in fact, no, that isn’t the case either; refactoring or opening up… Read more »
Eugen Paraschiv
Guest

Well what you’re describing is the standard way to implement the pattern. What I am aiming to describe here is an alternative way. Yes, you need to remember to initialize it, which is a downside. However, in a large enough system, with a high number of copy-paste DAO implementation, the upside of getting rid of all that cruft may be well worth it.
Thanks.

Girish Mahajan
Guest

you’d try using:

clazz = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

Eugen Paraschiv
Guest

Hey Girish – yes, this has been proposed a few years back – also in the comments of this article. While it’s a valid approach, I prefer to pass the class, since it’s a bit more readable. Hope this makes sense. Cheers,

Eugen.

Meeraj
Guest

How is this different from using the entity manager directly from your servivce class. IMHO the whole idea of using DAOs is an unncessary level of indirection.

Meeraj

Eugen Paraschiv
Guest

One difference is the flexibility to change – using the entity manager directly means tying much of the codebase to the JPA API. Using a DAO means tying a single class, so if you ever want to change – you only change this single class, with a clear responsibility. However, I fully agree – not all projects need a DAO and many projects use one without a good reason to – this is for when a DAO layer is actually needed.

Friend
Guest
Nice, thanks for the post, just one thing, injecting a “fat” generic DAO into every use case, even ones that don’t require all of the functionality probably ain’t the best. A possible refinement of this would be to divide the generic interface into smaller ones each of which defining a function, eg IPersistable, IDeleteable, IUpdateable, IRetrievable. Might have to forgo not creating sub interfaces for particular use cases, but i prefer a leaner use case than a leaner code base Then ensure that you inject by only the interface thats required, hiding some of the additional functionality that is perhaps… Read more »
Eugen Paraschiv
Guest

In my view, that depends on what your application looks like. I described a very standard DAO-Service-Controller (presumably) separation of responsibilities – if that’s the case, you can always choose to publish a smaller or more focused API from the Service layer if that makes sense. Splitting this DAO into a few responsibilities may also make sense, but these smaller and more focused responsibilities (and APIs) can still use the same technique – have a single, generic implementation instead of many similar ones.
Thanks for the feedback.
Eugen.

hammerha
Guest

In you AbstractHibernateDAO class, there’s no getById method. Maybe, typo of findOne?

Eugen Paraschiv
Guest

findOne is getById yes.

wpDiscuz