Home > JEE Development, Java > A Handy and Highly Reusable JPA 2.0 Data Access Object

A Handy and Highly Reusable JPA 2.0 Data Access Object

Hi ! In this post I’ll show you a highly reusable Data Access Object for Java web applications which will reduce the development time of your DAOs.

Consider the following DAO and it’s implementation.

public interface UserDao {

     User storeUser(User user);

     void removeUser(User user);

     List<User> findAllUsers();

     User findUserById(long id);

}
public class JpaUserDao implements UserDao {

     @PersistentContext
     private EntityManager em;

     @Override
     public User storeUser(User user) {
          User merged = em.merge(user);
          em.persist(merged);
          return merged;
     }

     @Override
     public void removeUser(User user) {
          em.remove(user);
     }

     @Override
     public List<User> findAllUsers() {
          return (List <User>) em.createQuery("from User").getResultList();
     }

     @Override
     public User findUserById(Long id) {
        return em.find(User.class, id);
     }
}

It looks pretty cool ! We just coded a JPA 2.0 Data Access Object. This means we used standard Java libraries (javax.persistence package).

The problem with the above code is that you are going to repeat it for each entity in your application. Having those 40 lines of CRUD (Create-Remove-Update-Delete) code doesn’t only lead you to more development effort but only to a poorly maintainable application. A code generator like Spring Roo can do the work but we can avoid any code generation tools by applying some Java inheritance and spicy code like using Java Generics and Reflection. You’ll see how to use those forty lines for infinite entities DAOs.

First of all let’s create a generic DAO:

public interface BaseDao<T> {

	T store(T t);

	void remove(T t);

	List<T> findAll();

	T findById(long id);

}

The above interface will be extended by all your DAO interfaces.

We should now create a generic implementation of the above interface which will be extended by all the DAO implementations of your application.

@SuppressWarnings("unchecked")
@Repository
public abstract class JpaBaseDao<T extends Serializable> implements BaseDao<T> {

	private Class<T> clazz;

	@PersistenceContext
	protected EntityManager em;

	protected JpaBaseDao() {
		Class<T> getClass = (Class<T>) getClass();
		ParameterizedType genericSuperclass = (ParameterizedType) getClass.getGenericSuperclass();
		clazz = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
	}

	@Override
	public T store(T t) {
		T merged = em.merge(t);
		em.persist(merged);
		return merged;
	}

	@Override
	public void remove(T t) {
		em.remove(t);
	}

	@Override
	public List<T> findAll() {
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<T> query = cb.createQuery(clazz);
		query.from(clazz);
		return em.createQuery(query).getResultList();
	}

	@Override
	public T findById(long id) {
		return em.find(clazz, id);
	}
}

The @Repository annotation is a Spring annotation which Indicates that an annotated class is a “Repository” (or “DAO”). A class thus annotated is eligible for Spring DataAccessException translation. The annotated class is also clarified as to its role in the overall application architecture for the purpose of tools, aspects, etc. Note that you don’t need it if you are not using Spring.

The @PersistenContext is a javax.persistence annotation which expresses a dependency on an EntityManager persistence context.

The final code:

public interface UserDao extends BaseDao<User> {

     // Custom access methods (which are not CRUD's) go here

}
public class JpaUserDao extends JpaBaseDao<User> implements UserDao {

   // Custom access methods implementations go here

}

Then in a service layer, let’s say a Spring service, you can access the BaseDao CRUD methods from any DAO which inherits it.

@Service
public class UserService {

     @Autowired
     private UserDao userDao;

     @Transactional
     public User saveUser(User user) {
          return userDao.store(user);
     }

}

Well, that’s all ! I hope you find it useful.

If you enjoyed this post follow me on twitter or leave a feedback !

Share
  1. R.
    January 6th, 2011 at 17:37 | #1

    What I would add to this generic dao is the query method or methods (query, single result query, count query)

    Nice post.

  2. January 6th, 2011 at 20:06 | #2

    Hi ! Thanks for the feedback ! It would be nice to have methods like

    findManyBy(Criterion… criterions)

    (the three points mean multiple parameters)

    Unluckily, Criterion and Session belong to the Hibernate framework.

    Then it would be easy to add custom dao methods like


    public List findUsersByNameAndAge(String name, int age) {
    userDao.findManyBy(Restrictions.eq(“name”, name), Restrictions.ge(“age”, age)).
    }

    The findManyBy(Criterion… criterions) implementation in the JpaBaseDao would be something like:


    public List findManyBy(Criterion… criterions) {

    Criteria criteria = session.createCriteriaQuery(clazz);
    for (Criterion criterion : criterions) {
    criteria.add(criterion);
    }
    return criteria.list();
    }

    Keep around !

  3. abel
    January 6th, 2011 at 20:22 | #3

    Hi,

    if you’re allowed to use Spring (as I suppose you are, as you’re using Spring annotations such as @Repository) you can use Hades (http://hades.synyx.org/) to do (almost) all the work for you.

  4. January 7th, 2011 at 00:39 | #4

    @abel
    The link doesn’t work :(

  5. August 29th, 2011 at 00:56 | #5

    Based on yourself to increase the risk for judgements can definitely always be distressing along with frustrating. Many of us produce this particular capability throughout our own existence. Honestly it will take more than just taking place to happen.

  1. January 9th, 2011 at 12:21 | #1
*