Rethinking the traditional DAO pattern

Back in the Age of Aquarius, a popular pattern emerged in the Java world dubbed “the data access object“, which essentially

“separates a data resource’s [hip] client interface from its data access mechanisms”

meaning that clients to a particular domain object were shielded from the actual implementation of communicating with a particular database. Provided that clients worked with the interface type, implementations could be switched out (the database could migrate from DB2 to Oracle, for instance or one DAO type could leverage Hibernate, another IBATIS). This pattern had the bogue consequence, though, of logically dividing up a data layer into two types– DAOs and individual domain objects.

think!

For instance, if you had a copasetic Customer domain object, you would also have a CustomerDAO interface type– your Customer object would essentially be a struct and the DAO type would handle CRUD (create, read, update, delete) operations. If you needed to find a particular customer, you’d ask the DAO type, for example, invoking the findCustomer(long id) method on the CustomerDAO object, which would return a fully populated Customer object.

This pattern seemed well and good at the time– I admit to using it extensively on a large project ages ago (after disco though); however, after a while it seemed to be a lot of work– if, because it was my bag, I wanted a Customer object, why did I have to ask the CustomerDAO for it? Why couldn’t I just ask the Customer itself? On top of that, if I wanted to create a new Customer, I had to first populate a Customer object and then pass it to the DAO type and invoke the create method.

I’m sure at the time a lot of smart people eschewed this uptight pattern and designed more natural domain objects; but for me, the tides changed when I read an interesting article about Naked Objects and then looked deeply at Rails (and subsequently, Grails) as they came to mature– these frameworks have no notion of a DAO type– your domain object (Customer) does everything for you– you can create new Customers, save instances, find instance, etc.

I recently found myself building a domain model in Java without the luxury of Grails or GORM; however, I did employ Hibernate and Spring. My initial effort starting going down the traditional DAO-domain object pairing but I quickly found myself disgusted– as a result I started playing around with combining the duo into something as hip (and polished) as what Grails/Rails would give you. My goal, of course, to provide a domain object that handled everything rather than having clients of the domain object have to work with two different trippin’ objects.

In the end, I still have two different objects and an interface type to link them (via Spring); however, clients need only work with one hip type– the domain object. My domain objects support instance methods like create, remove, and update and class methods for find-like methods.

I nonetheless still have a DAO object– it’s essentially a Spring wired HibernateTemplate– this object supports the true CRUD logic and is directly bound to Hibernate. For example, given a Race domain object, the DAO looks like this (minus some instance and class methods, but you’ll get the point):

class RaceDAOImpl implements RaceDAO {
 private SessionFactory sessionFactory;

 public RaceDAOImpl() {
  super();
 }

 public void setSessionFactory(final SessionFactory sessionFactory) {
  this.sessionFactory = sessionFactory;
 }

 public void create(final Race race) {
  final HibernateTemplate tmplte =
     new HibernateTemplate(this.sessionFactory);
  tmplte.save(race);
}

//...

public Race findByName(final String name) {
 final HibernateTemplate hibernateTemplate = new HibernateTemplate(this.sessionFactory);
 return (Race) hibernateTemplate.execute(new HibernateCallback() {
   public Object doInHibernate(Session session) throws HibernateException {
    return session.createQuery(
    "from ... name = ?")
    .setString(0, name.trim())
    .uniqueResult();
   }
  });
 }

//...
}

Note that this class isn’t public– it isn’t intended for outside consumption– the only client to this class (which will be shown shortly) is the domain object (which lives in the same package).

With this DAO object, I extracted an interface type– RaceDAO. This interface is the link between the domain object (Race) and the DAO (that is, the domain object will work with the interface type not the implementation or because it’s everyone’s bag to describe things in terms of coupling– the domain object is loosely coupled to the DAO implementation).

interface RaceDAO {
 Collection<Race> findAll();
 Race findById(long id);
 Race findByName(String name);
 //...other finders...
 void create(Race race);
 void update(Race race);
 void remove(Race race);
}

The domain object (which clients rely on) then relies on Spring (which basically acts as a factory) and composition to expose instance and class methods that indirectly (i.e. delegate via composition) leverage Hibernate to manipulate persistence.

For instance, the Race domain object looks like a normal, hip domain object– it contains various properties (and consequentially getters and setters) related to races (races have runners and results, etc) like so:

public class Race {
 private long id;
 private String name;
 private Date date;
 private double distance;
 private Set<Runner> participants;
 private Set<Result> results;
 private String description;

 //.....more to come
}

The next step could have unfolded in a number of different ways; however, I kept on truckin’ and ended up with something that works– there are certainly pros and cons associated with my choices though (I will point those out shortly).

The DAO interface is linked via Spring in a static block in the domain object like so:

private final static RaceDAO dao;

static {
 ApplicationContext context =
   new ClassPathXmlApplicationContext("spring-config.xml");
 dao = (RaceDAO) context.getBean("race_dao");
}

Note that the type in the domain object is the interface (RaceDAO) not the implementation — Spring is returning some type that is bound to the String race_dao, which in my case is the Hibernate template type shown earlier.

Thus, because the RaceDAO is a static type, I can then expose a series of class methods on the domain object for finding particular race instances like so:

public static Collection<Race> findAll(){
 return dao.findAll();
}

public static Race findById(long id) {
 return dao.findById(id);
}
//...others...

Plus, instance methods on the domain object also delegate to the interface type:

public void create() {
 dao.create(this);
}

Now clients of a particular domain object don’t need to handle or work with various copasetic objects– they work exclusively with a domain object (much like you would in Grails, for instance). For example, the following easyb scenario demonstrates the behavior of a Race instance:

scenario "Race should support finding races by name", {

 when "the find by name method is called", {
  race = Race.findByName("Leesburg Marathon")
 }

 then "the race should have 100 runners", {
  race.participants.size().shouldBe 100
 }
}

As you see in the Groovy code above, the findByName method is a class method– it returns a Race instance, which clients can then work with.

Instance methods on the domain object work too, for example, creating a new race instance and persisting it is as easy as invoking the create method:

scenario "the domain object should faciliate creating new instances", {
 given "a new race is created", {
  new Race("SML 10K", new Date(), 6.2,
     "race the hills of Smith Mountain lake").create()
 }
 then "the domain class should actually find it by name", {
  race = Race.findByName("SML 10K")
  race.description.shouldBe "race the hills of Smith Mountain lake"
 }
}

As I mentioned earlier, there are some bogue disadvantages to this strategy– that is, because it’s its bag, the static block forces clients to load some instance of the DAO– without mocking that instance out, the domain object becomes somewhat heavy. For instance, loading the Race class with a Hibernate wired DAO means that a database must be up and running. Thus, without some mocking of the DAO interface type (and subsequent wiring of Spring) these domain objects can be hard to truly unit test.

The advantage of this strategy is that clients don’t have to deal with a DAO type– they have a more neat-o-natural interface to work with– that being the business object itself (i.e. Customer or Race or Runner, etc). There are still two objects (and a binding type) to work with; however, the DAO is hidden. And in keeping with the spirit of the original DAO pattern, implementers are free to create varying instances of the DAO (should they actually need more than one– unit testing certainly comes to mind for a need to create at least one other instance).

The data models offered by frameworks like Grails and Rails are pretty hippingly sophisticated as well as elegant; what’s more they are easy to learn and natural to use. At this point, however, GORM (Grails magic data layer sauce) isn’t available as a stand alone project for Java developers; consequently, hip developers are left to rolling their own models (which leverage Hibernate, JDBC, IBATIS, etc), modeled after said project’s elegance.

The DAO pattern as it was authored (and implemented) back in the day is heavy, man; however, by applying a bit of Spring (or some other IOC framework) and leveraging a restrictive class modifier (to thus hide objects from clients), you can create more natural domain objects that still live up to the promised flexibility of the DAO pattern. Can you dig it, baby?

Related odds and ends
 

18 Responses to “Rethinking the traditional DAO pattern”

  1. on 17 Jun 2008 at 3:55 pm Jeremy Anderson

    I like what you’ve started here. I too looked at Rails and Grails a couple of years back and wondered the same question, “Why do I have to ask a DAO to act on my object’s behalf?” Thanks again, catch you on the flip side…

  2. on 17 Jun 2008 at 5:10 pm Brian Reilly

    I really like the idea of getting rid of (or hiding) DAOs in some cases. However, I hesitate to completely fold the DAO into the domain object.

    Many domain objects have some sort of logical container. If we didn’t have a database, we would either create an object and put it in its container or ask the container to create new object and add it to itself. For domain objects that have a logical container, exposed CRUD methods aren’t necessary. (Well, they shouldn’t be, but sometimes web application programming makes that difficult… but I’m sure there are ways of dealing with that.)

    As for find methods, there’s nothing wrong with using a DAO. Putting find methods on the domain class make the class represent both objects of that type and the database that persists its instances. This feels like a mixing of concerns to me. Even in the example where the underlying implementations are separate, the API still feels mixed, and the domain object feels cluttered with all of those proxy methods.

    Still, I really like what you’ve done here. I’m hoping that the ideas get carried forward and that new patterns continue to emerge for working with databases from object-oriented languages.

  3. on 17 Jun 2008 at 5:12 pm Andy

    Brian-

    Good points– the mixing of concerns is definitely there– moving the finders to the domain objects, for me, seems more natural. Ultimately, I’d rather work with fewer objects (as a client, that is). Thanks for sharing!

  4. on 17 Jun 2008 at 5:33 pm javaguy44

    Look @ ibatis + ibator. ibator will generate those methods you want for domain object.

    I wouldn’t put dao methods / anything extra in my domain object if you are sending it over the wire…or could do so in the future

    I guess if you can guarantee a single jvm and a webapp and your response is a dynamic html file then fine…else I wouldn’t

  5. on 17 Jun 2008 at 5:57 pm Andy

    javaguy44- good point on the distributed concern– yes, this is single VM solution.

  6. on 17 Jun 2008 at 8:48 pm Philip Dorrell

    See Sculptor = a Crud DSL.

  7. on 17 Jun 2008 at 8:54 pm Andy

    Philip- Sculptor looks interesting– know of a Java equivalent?


  8. [...] Rethinking the traditional DAO patternscenario "the domain object should faciliate creating new instances", { given "a new race is created", { new Race("SML 10K", new Date(), 6.2, "race the hills of Smith Mountain lake").create() } then "the domain class should actually …The Disco Blog - http://thediscoblog.com [...]

  9. on 18 Jun 2008 at 6:11 am smith mountain lake | Hottags

    [...] Rethinking the traditional DAO patternscenario "the domain object should faciliate creating new instances", { given "a new race is created", { new Race("SML 10K", new Date(), 6.2, "race the hills of Smith Mountain lake").create() } then "the domain class should actually …The Disco Blog - http://thediscoblog.com pay per click advertising [...]

  10. on 18 Jun 2008 at 12:41 pm James

    Thanks for sharing your approach.
    Perhaps you’ve considered this, but I think spring could wire your domain object with aspectJ or loadtimeweaving, instead of the static code to find or load the spring context.

  11. on 18 Jun 2008 at 12:49 pm Andy

    James- I didn’t consider the aspect approach, but I think it’s an excellent idea!

  12. on 24 Jun 2008 at 8:56 pm Stephan Schmidt

    I still like and use Dao objects. Folding the Dao into the Domain object combines two concerns, reduced reusability, makes testing more difficult and is harder to maintain.

    From my point of view, every class should satisfy one concern, not several ones. Perhaps that’s the reason I like ideas like Qi4J for it’s composite oriented programming.

    Peace
    -stephan

  13. on 25 Jun 2008 at 8:53 pm Andy

    Stephan- you are correct– my approach does make testing a bit more challenging– so long as your domain objects remain simple bean-like objects though, do you really need to unit test them? That is, don’t they only hold true meaning when they are wired to some data store? I’m thinking that integration-like tests are more realistic for domain objects; consequently, I don’t mind too much that to work with these objects, as I’ve coded them, I need to have a live database.

    You raise great points– thanks for sharing! And thanks for the pointer to Qi4J! This is interesting stuff!

  14. on 29 Jun 2008 at 7:19 am DZone weekly links #3 | Sergi Castillo

    [...] Rethinking the traditional DAO pattern [...]

  15. on 30 Jun 2008 at 9:09 am Software Development

    hey

    Really nice tips!

    will try to keep it in my mind

    thanks!

  16. on 05 Jul 2008 at 11:45 am rails 2 0 oracle

    [...] resource??s hip client interface from its data access mechanisms??? meaning that clients to a partichttp://thediscoblog.com/2008/06/17/rethinking-the-traditional-dao-pattern/scroll down to read an excerpt from this article - ACM QueueTune in to learn how oracle plans to [...]

  17. on 08 Jul 2008 at 2:17 pm Kenrick Chien

    Interesting idea, to put CRUD logic in the domain object/POJO. Adding to what James said, you could use “lookup method injection” (see section 3.3.8.1 at http://static.springframework.org/spring/docs/2.0.x/reference/beans.html) anytime you wanted your POJO, and have Spring manage the DAO dependency by injecting it, instead of looking it up statically.
    This way, if you’re using the full Spring stack, your beans would all be wired when your container starts up and
    the domain object could be easily unit tested by mocking out the DAO interface w/EasyMock, JMock, etc.

    Thanks for sharing this idea.

  18. on 08 Jul 2008 at 2:55 pm Andy

    Wow, Kenrick– that’s a slick idea! I need to explore method injection more as its a powerful technique in Spring that is similar to a lot of the MOP features you get in Groovy. Thanks for pointing that out, man!

Trackback this Post | Feed on comments to this Post

Leave a Reply