Vincent Partington has more than 10 years of enterprise Java experience. He has written and presented on topics as diverse as performance, security, RIA, and persistence technologies. Vincent Partington is the Chief Technical Officer of XebiaLabs where he is responsible for their flagship deployment automation product Deployit. Vincent is a DZone MVB and is not an employee of DZone and has posted 25 posts at DZone. You can read more from them at their website. View Full User Profile

JPA Implementation Patterns: Data Access Objects

07.22.2009
| 59457 views |
  • submit to reddit

The JPA, short for Java Persistence API, is part of the Java EE 5 specification and has been implemented by Hibernate, TopLink, EclipseLink, OpenJPA, and a number of other object-relational mapping (ORM) frameworks. Because JPA was originally designed as part of the EJB 3.0 specification, you can use it within an EJB 3.0 application. But it works equally well outside of EJB 3.0, for example in a Spring application. And when even Gavin King, the designer of Hibernate, recommends using JPA in the second edition of Hibernate in Action, a.k.a. Java Persistence with Hibernate, it's obvious that JPA is here to stay.

Once you get over your fear of annotations ;-), you find that there is plenty of literature out there that explains the objects and methods within the API, the way these objects work together and how you can expect them to be implemented. And when you stick to hello-world-style programs, it all seems pretty straight forward. But when you start writing your first real application, you find that things are not so simple. The abstraction provided by JPA is pretty leaky and has ramifications for larger parts of your application than just your Data Access Objects (DAO's) and your domain objects. You need to make decisions on how to handle transactions, lazy loading, detached object (think web frameworks), inheritance, and more. And it turns out that the books and the articles don't really help you here.

A:link {color: blue;} A:visited {color: #A000A0;} html body p { line-height: 120%; } ul li, ul.menu li, .item-list ul li, li.leaf { list-style-type: disc; list-style-position:outside;} ol li, ol.menu li, .item-list ol li, li.leaf { list-style-type: decimal; list-style-position:outside;}

At least, that is what I discovered when I really started using JPA for the first time. In the coming weeks, I would like to discuss the choices I came up against and the decisions I made and why I made them. When I'm done, we'll have a number of what I would like to not-too-modestly call JPA implementation patterns. ;-)

Do we really need a DAO?

So, let's start with the thing you would probably write first in your JPA application: the data access object (DAO). An interesting point to tackle before we even start is whether you even need a DAO when using JPA. The conclusion of that discussion more than a year ago was "It depends" and while it is very hard to argue with such a conclusion :-), I would like to stick with the idea that a DAO does have its place in a JPA application. Arguably it provides only a thin layer on top of JPA, but more importantly making a DAO per entity type gives you these advantages:

  • Instead of having to pick the right EntityManager method every time you want to store or load data, you decide which one to use once and you and your whole team can easily stick to that choice.
  • You can disallow certain operations for certain entity types. For example, you might never want your code to remove log entries. When using DAO's, you just do not add a remove method to your LogEntry DAO.
  • Theoretically, by using DAO's you could switch to another persistence system (like plain JDBC or iBATIS). But because JPA is such a leaky abstraction I think that that is not realistically possible for even a slightly complex application. You do get a single point of entry where you can add tracing features or keep performance statistics.
  • You can centralize all the queries on a certain entity type instead of scattering them through your code. You could use named queries to keep the queries with the entity type, but you'd still need some central place where the right parameters are set. Putting both the query, the code that sets the parameters, and the cast to the correct return type in the DAO seems a simpler thing to do. For example:
    public List<ChangePlan> findExecutingChangePlans() {
    Query query = entityManager.createQuery(
    "SELECT plan FROM ChangePlan plan where plan.state = 'EXECUTING'");
    return (List<ChangePlan>) query.getResultList();
    }

So when you decide you are going to use DAO's, how do you go about writing them? The highlighted (in bold) comment in the Javadoc for Spring's JpaTemplate seems to suggest that there's not much point in using that particular class, which also makes JpaDaoSupport superfluous. Instead you can write your JPA DAO as a POJO using the @PersistenceContext annotation to get an EntityManager reference. It will work in an EJB 3.0 container and it will work in Spring 2.0 and up if you add the PersistenceAnnotationBeanPostProcessor bean to your Spring context.

The type-safe generic DAO pattern

Because each DAO shares a lot of functionality with the other DAO's, it makes sense to have a base class with the shared functionality and then subclass from that for each specific DAO. There are a lot of blogs out there about such a type-safe generic DAO pattern and you can even download some code from Google Code. When we combine elements from all these sources, we get the following JPA implementation pattern for DAO's.

The entity class

Let's say we want to persist the following Order class:

@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue
private int id;
private String customerName;
private Date date;

public int getId() { return id; }
public void setId(int id) { this.id = id; }

public String getCustomerName() { return customerName; }
public void setCustomerName(String customerName) { this.customerName = customerName; }

public Date getDate() { return date; }
public void setDate(Date date) { this.date = date;}
}

Don't worry too much about the details of this class. We will revisit the specifics in other JPA implementation patterns. The @Table annotation is there because ORDER is a reserved keyword in SQL.

The DAO interfaces

First we define a generic DAO interface with the methods we'd like all DAO's to share:

public interface Dao<K, E> {
void persist(E entity);
void remove(E entity);
E findById(K id);
}

The first type parameter, K, is the type to use as the key and the second type parameter, E, is the type of the entity. Next to the basic persist, remove, and findById methods, you might also like to add a List findAll() method. But like the entity class itself, we will revisit the DAO methods in later JPA implementation patterns.

Then we define one subinterface for each entity type we want to persist, adding any entity specific methods we want. For example, if we'd like to be able to query all orders that have been added since a certain date, we can add such a method:

public interface OrderDao extends Dao<Integer, Order> {
List<Order> findOrdersSubmittedSince(Date date);
}

The base DAO implementation

The third step is to create a base JPA DAO implementation. It will have basic implementation of all the methods in the standard Dao interface we created in step 1:

public abstract class JpaDao<K, E> implements Dao<K, E> {
protected Class<E> entityClass;

@PersistenceContext
protected EntityManager entityManager;

public JpaDao() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
}

public void persist(E entity) { entityManager.persist(entity); }

public void remove(E entity) { entityManager.remove(entity); }

public E findById(K id) { return entityManager.find(entityClass, id); }
}

Most of the implementation is pretty straight forward. Some points to note though:

  • The constructor of the JpaDao includes the method proposed by my colleague Arjan Blokzijl to use reflection to get the entity class.
  • The @PersistenceContext annotation causes the EJB 3.0 container or Spring to inject the entity manager.
  • The entityManager and entityClass fields are protected so that subclasses, i.e. specific DAO implementations, can access them.

The specific DAO implementation

And finally we create such a specific DAO implementation. It extends the basic JPA DAO class and implements the specific DAO interface:

public class JpaOrderDao extends JpaDao<Integer, Order> implements OrderDao {
public List<Order> findOrdersSubmittedSince(Date date) {
Query q = entityManager.createQuery(
"SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");
q.setParameter("date_since", date);
return (List<Order>) q.getResultList();
}
}

Using the DAO

How you get a reference to an instance of your OrderDao depends upon whether we use EJB 3.0 or Spring. In EJB 3.0 we'd use a annotation like this:

@EJB(name="orderDao")
private OrderDao orderDao;

while in Spring we can use the XML bean files or we can use autowiring like this:

@Autowired
public OrderDao orderDao;

In any case, once we have a reference to the DAO we can use it like this:

Order o = new Order();
o.setCustomerName("Peter Johnson");
o.setDate(new Date());
orderDao.persist(o);

But we can also use the entity specific query we added to the OrderDao interface:

List<Order> orders = orderDao.findOrdersSubmittedSince(date);
for (Order each : orders) {
System.out.println("order id = " + each.getId());
}

With this type-safe DAO pattern we get the following advantages:

  • No direct dependency on the JPA api from client code.
  • Type-safety through the use of generics. Any casts that still need to be done are handled in the DAO implementation.
  • One logical place to group all entity-specific JPA code.
  • One location to add transaction markers, debugging, profiling, etc. Although as we will see later, we will need to add transaction markers in other parts of our applications too.
  • One class to test when testing the database access code. We will revisit this subject in a later JPA implementation pattern.

I hope this convinces you that you do need DAO's with JPA. :-)

And that wraps up the first JPA implementation pattern. In the next blog of this series we will build on this example to discuss the next pattern. In the meantime I would love to hear from you how you write your DAO's!

From http://blog.xebia.com

Published at DZone with permission of Vincent Partington, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Mladen Girazovski replied on Wed, 2009/07/22 - 3:42am

IMHO the DAO Pattern is overdue to be replaced by Repositories, since a DAO is part of the Persistence Tier, it leads to Busniesslogic leaking into the Persistence TIer. Repositories on the other hand are Part of the Domain Model, and therefore a good place for Businesslogic.

 

 

 

Gabor Farkas replied on Wed, 2009/07/22 - 7:44am

Hi. Regarding the four advantages you mention for the DAO pattern, I don't really get the first point

About the others, I think that when starting a new project, you should definitely know on which platforms you are propable to deliver the system, so you choose JPA only if you're really sure that it will be availabe on all platforms needed. From this point, using DAOs I consider also as coding and architectural overhead. You can easily manage your queries and the exposed functionality by well designing your business manager beans.

I usually don't support separating DAOs and business logic, i also think that you'll just have to introduce the methods in your DAO which properly support your business logic. Of course, if you have to expose your DAO as a service, that's a different case.

Anyway, DAO pattern does not save you database tier migrating work. You can write generic persist methods on almost all platforms, but your DAO and business methods will still heavily use JPA queries (like your find orders method). Also, when you are using JPA, you'll heavily rely on the (lazy) fetching of associated entities.

Ryan Developer replied on Wed, 2009/07/22 - 8:07am

When your app uses multiple databases, @PersistenceContext without an attribute to tell it the persistence unit name will not work.   In this case I add a setEntityManager method to DAO subclasses and annotate it with @PersistenceContext(unitName="whatever"). The method calls the setEntityManager on the superclass.

 I always separate data access from business logic using DAOs so that I can unit test business logic with mock data access objects. This benefit alone makes it worth using DAOs. 

Ryan Developer replied on Wed, 2009/07/22 - 8:17am

I also add a findAll method to the generic DAO which uses the EntityManager's findAll method.   I read that findById and findAll take advantage of the 2nd level cache without querying the database. If you write your own queries then the query will be executed, it will iterate through each result, check the version and either load a new entity insntance or load the entity from 2nd level cache.   What I don't like about my findAll method is that there is no ordering, and since ordering is specific to each entity I am considering removing the findAll method and making each DAO subclass implement its own using a query. 

 

Cloves Almeida replied on Wed, 2009/07/22 - 10:14am

My eyes burns on seeing so much boilerplate code. Are you seriously talking about  "overcoming your fear of annotations"?

The DAO pattern is monstrous. What's the problem about having rich objects? Please give a good reason why the code below is "wrong":

public class Person {
  private Long id;
  private String name;
  private Set<Account> accounts; 
  //.. getters and setters
  public static Person findById(EntityManager entityManager, Long id) { ... }
  public static Date findByDate(EntityManager entityManager, Date date) { ...}

Fowler's Active Record makes way more sense.

Jim Mccollom replied on Wed, 2009/07/22 - 3:27pm in response to: Cloves Almeida

Why would I pass the EM around when I can get it correctly injected ? Your proposal would never work in JEE anyways.

Jim Mccollom replied on Wed, 2009/07/22 - 3:29pm

Bravo ! I am really sick of seeing tightly coupled persistence code within services. Your business logic shouldn't care how the data was obtained or how to save it.

Vincent Partington replied on Thu, 2009/07/23 - 12:44pm in response to: Gabor Farkas

@hhcofcms: The first advantage is about being able to chose once how and when to use persist, merge, etc. and then enforcing that for all code that uses JPA. These choices are something future articles will adress.

 I think DAO's and business logic should be separated because I do not want to riddle my business logic with JPA code and queries. It's about separation of concerns. The argument about architectural overhead is one I hear often, but I don't really see how separating business logic from JPA code adds to the architecture. It's just about having separate classes.

 

Vincent Partington replied on Fri, 2009/07/24 - 2:58am in response to: Cloves Almeida

@Cloves Almeida: Having the data access in the domain objects is not necessarily "wrong", but I feel that it is better to separate the concerns of the domain objects itself from the concern of moving it from and to the database.

In his discussion of the Active Record pattern Martin Fowler mentions that it "gets very messy" when the mapping between your objects and the database is not straightforward. In that case he recommends the Data Mapper pattern, of which this DAO pattern is the JPA translation.

Gabor Farkas replied on Thu, 2009/07/23 - 1:19pm

Ryan has a good point with using mock daos for unit testing - this aspect i didn't consider.

Vincent: thanks for the explanation. About the architectural thing: in my point of view, creating separate classes is indeed an architectural choice - you separate the data related methods (which need do use jpa/jdbc directly) from those that build upon them, and this actually forms a layer.

Having your database related code in separated classes can indeed result in a clearer code - you don't see queries in your business code, but well named DAO methods, so it can be easier to read. On the other hand, when needing another type of query or other kind of database operation, you are "forced" to create the corressponding DAO method, which can be an annoying overhead during development.

What came into my mind is that maybe the good choice about whether to separate the DAO layer or not can be made by taking the complexity (or maybe, the level of abstraction) of the business functionality. If the business functionality is "closer" to the data themselves, that is, the business methods just modify some data of some associated entities, the presence of queries and other database related code does not ruin the readability (and thus the maintainability) of the code. However, if the business functions are defined by higherly abstracted operations, these operations are to be properly named and put into DAO classes.

Vincent Partington replied on Fri, 2009/07/24 - 1:02am in response to: Gabor Farkas

@hhcofcmds: Your last point is good one: when the business logic is trivial and mostly doing CRUD operations, then separating your code into a business and a DAO layer is just overhead. In that case you could even say that the data access code is the business logic! As always: it depends. ;-)

Freddy Daoud replied on Tue, 2009/07/28 - 7:09pm

Cloves Almeida: my eyes are burning from looking at your code. So you're telling me you basically copy-paste your findById method in all your model objects? I prefer one generic Dao that takes the model class as a parameter and does all the basic operations. Your static methods have no reuse whatsoever.

EDIT: these methods might be relevant in Rails where Ruby allows for some reusable magic, but I don't see the value of copy-pasting such code in static Java methods. You are replacing boilerplate code by boilerplate code!

Gikku Kumar replied on Fri, 2009/10/02 - 12:19am

I would like to add UOW in  this DAO pattern to hold EntityManager. What you guys thinkin!.

private static UnitOfWork uow=new UnitOfWork() ;

private static class UnitOfWork extends ThreadLocal{

@persistenceContext

EntityManager em;

protected Object initialValue(){

return em;

}

public static EntityManager getUnitOfWork(){

return (EntityManager)uow.get();

}

}

Stephane Dupont replied on Wed, 2009/10/21 - 3:07pm

Hi Vincent,

I found your article very interesting, but I was wondering:  when you are in EJB 3 and you suggest tu use the

@EJB(name="orderDao") annotation, what you're saying, if I understand correctly, is to transform your dao into a stateless EJB bean.

By doing that, you are "still" using the dao pattern but you are also introducing the complexity of ejb (transaction, ejb pool instance, etc.) by tranforming your dao into an ejb.

I guess that you are doing that to have the dependency injection that is not available to ordinary pojo, but is there another way of achieving the same goal ?

If, for instance, I wanted to test the same pattern outside a container, without using spring, do you have some suggestions ?

The only one I found till now are implementing a method setEntitymanager(...) in the generic dao but i must admit that i'm not too satisfied with that solution yet. That's a way I found in the Hibernate caveaEmptor example.

Stephane Dupont replied on Thu, 2009/10/22 - 10:33am

Hi again Vincent,

There is also something that is redundant in the example:

First, 

public interface OrderDao extends Dao<Integer, Order>

and second

public class JpaOrderDao extends JpaDao<Integer, Order> implements OrderDao

There is two places where we have to write the <Integer, Order> stuff. If a way could be found to avoid this, the solution would be cleaner. It's just a suggestion, I don't have a solution yet !

 

Riadh Riadhh replied on Thu, 2009/10/29 - 6:58am

hi

i read this article and it is very important thanks 

in my case, i have a simple java application(i am not working with ejb  or spring)

so how can i  get a reference to an instance of my UtiliasteurDao

i have tryied this:

JpaUtilisateurDao orderDao=new JpaUtilisateurDao();
        Utilisateurs o = new Utilisateurs();
        o.setName("TestName");
        o.setType("testType");
        o.setPassword("dao pawd");
        orderDao.persist(o);

but i had a nullpointer exceptio that point to  :   

public void persist(E entity) { entityManager.persist(entity);

Vincent Partington replied on Sun, 2009/11/01 - 8:40am in response to: Stephane Dupont

@Stephane: I am indeed doing that to get dependency injection in an EJB 3.0 environment. But, as the blog points out, you can also use other dependency injection frameworks such as Spring. In that case your code would look like this:

@Autowired
public OrderDao orderDao;

Vincent Partington replied on Sun, 2009/11/01 - 8:42am in response to: Gikku Kumar

@ganu98: Using a thread local to pass around the entity manager reference seems complicated to me. When not let your dependency injection framework, be it EJB 3.0 or Spring, solve this for you? In that case all you need is the @PersistenceContext annotation. What problem would this UOW idea solve?

 

Vincent Partington replied on Sun, 2009/11/01 - 8:44am in response to: Riadh Riadhh

@riadhhwajdii: If you are not letting EJB 3.0 or Spring wire your beans for you, you'll have to it manually. So you'll have to make sure that your DAO has a reference to an EntityManager. But my suggestion would be to use Spring for this. It is really light weight and can be used in the smallest Java applications with very little startup and runtime overhead.

 

Ralph Soika replied on Fri, 2011/03/04 - 4:45pm

Working with generic value objects and jpa is shown by the implementation of the ImixsEntityService EJB. This service ejb is provided by the Imixs Workflow Project. It can be used to store objects independent from a specific Entity Bean. Also queries with JPQL are possible. See: http://www.imixs.org/jee/examples/entityservice.html

Carla Brian replied on Wed, 2012/08/01 - 6:00pm

Having the entity specific DAOs extend a generic interface may not always be the best idea. I only knew this from a forum that i have read as well. - Mercy Ministries

Bing Ren replied on Thu, 2014/02/27 - 1:22am

Hi,

I tried the code and would comment that in certain cases the generic JpaDao code in constructor to elicit generic type may not work. The reason is I am using CDI to inject the DAO, and the server (I am using JBoss) creates a proxy for the injected DAO, which is a sub class of the concrete DAO. I walked around this by using the following code to find out the immediate subclass of the general JpaDao. This works better, but still cannot gaurantee workable in all server environments under all circumstances.


    Class ascent = getClass();
     while (ascent.getSuperclass() != JpaDao.class)
       ascent = ascent.getSuperclass();
     ParameterizedType genericSuperclass = (ParameterizedType) ascent.getGenericSuperclass();
     this.entityClass = (Class<EntityType>) genericSuperclass.getActualTypeArguments()[1];

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.