Skip to main content

An interesting debate about JPA and the DAO

Posted by fabriziogiudici on February 7, 2009 at 10:00 PM PST

In these days I'm writing a draft for a post whose temporary title is "Two things that I don't like in JPA (and Wicket)". The post is about an architectural vision and some code to address it, but it's still too cumbersome to be published; in the meantime, NetBeans Dream Team fellow Adam Bien blogged about JPA and DAO, which generated some reaction by Scot McPhee.

I'm inviting you to read both posts since they are inspiring; to sum up their positions, Adam is saying that the EntityManager in JPA, used from the service layer, can replace the DAO pattern at the point that it may disappear in most cases; Scot is arguing that he doesn't like to mix his first-class objects (derived from the domain model) with things related to JPA, so the DAO or something similar is still needed.

My personal attitude would be with Scot - but there is a big "but" as you'll see later. I've been working with solutions that keep the JPA stuff well confined in its box since a few time (I posted a solution based on BeansBinding about one year ago) because I like too to work with first-class objects as Scot, for these reasons:

  1. code tends automatically to be tidier and more readable (see some of the Scot's examples);
  2. in particular, presentation-layer or client-layer code tends to be better, and in my experience these are the two places where most of changes occur;
  3. you can change the persistence implementation reducing the impact of the change.

Now the "but". In my opinion there's a winning sentence in Adam's post:

The architecture (even real live) is all about probability. If
something is likely to happen, we react to it. If something is rather
unlikely, we tend to ignore it.

I like to present this concept to people by comparing architecture choices to insurances against oddities. You must have an insurance about car accidents; you should have an insurance about losing baggage if you are a frequent flier; on the contrary an insurance about poisoning spiders bites is probably useless to many of us.

Elegant designs where you push abstraction to the maximum are very powerful and very flexible - but they cost more. I'm aware of the fact that correctly evaluating the cost of a technical solution is difficult without setting a precise context, but let me specify "they cost more at the beginning". If not only because there are less people around able to do them (do you want an example? Getting rid of getters and setters is acknowledged to be a better approach, but take any typical enterprise problem and count how many people is good in getting a robust solution with getters and setters, then how many are able to do the same without getters and setters).

Adam said that he met only very few cases in which a project switched the database vendor, and no cases in which the persistence moved to a different thing than a RDBMs. Why should you pay more for a thing that it's unlikely to happen? Sometimes, when it happens, a simpler solution might have paid for itself and it might turn out to be simpler to rewrite a component.

I'm playing the devil's advocate here. With my own projects I'm going Scot's way - and it actually happened that I'm moving some things from a RDBM persistence to a RDF facility. The problem is that simple solutions, such as the BeansBinding approach, proved to work well for a specific component, where persistent objects are nothing more than beans and there's a clear separation between data and services. For more generic cases, I'm still working to a general solution - the hard point that I'm addressing is how to encapsulate the managed/unmanaged handling of objects typical of JPA and other frameworks: if you want to deal with domain objects you don't want to mess around with entityManager.merge(). At the moment I have working code for it, but quite messy. Still it doesn't solve a similar problem in Wicket, where the problem is about attaching / detaching objects, definitely more complex than merging.

So in the end I'm always guessing whether all this effort is worth while or whether a simpler solution, such as Adam's, would make more sense. The hope, of course, is to find something really reusable that, once you've spent a considerable effort in designing it, can be easily adopted multiple times.

Comments

I already use JPA as replace for DAOs. In fact, I even name my EntityManager object as "dao" :) I like simple solutions. I don't think using more one layer is a good cost-benefit IN THIS CASE.

Hi Fabrizio, 1. Thanks for covering my post here. 2. In most cases I use DAOs too - but they always have additional responsibilities and the Service layer is not empty. If a Service only delegates to a DAO - then it is not worth to implement it (either the DAO or the Service -> I prefer to kill the DAO then :-))... 3. DAO are only the starting point of overengineering. Developers get the next idea and start to transforming JPA into DTOs - just to be independent from the domain objects... 4. The essence of my posts is: additional layers are not always a good thing - just think a little bit before introducing them. 5. You could avoid the use of em#merge, if you swich to PersistenceContext.EXTENDED and SFSB - but this brings other challenges :-). thanks again!, adam bien (http://blog.adam-bien.com)

@javawerks: How do you avoid a query explosion down in the entities, leaking application/domain specific stuff into each and every other application sharing the JPA-backend?

I've been using a generic entity manager for a few years, one for spring + jpa and another for spring + hibernate. No more DAOs! Just a single generic entity manager dependency-injected across a set of transactional services. KISS!

For small one-person projects, going without a DAO layer is not usually a problem. However, in the context of a team, particularly when the skill level varies among members, a DAO layer in my experience is necessary. Unfortunately, JPA doesn't make it particularly easy to work within a DAO layer as the various states of EntityBeans makes it difficult know if a persist or merge is required. However, the increased read-ability of code that utilize the Repository pattern should not be underestimated, as it can reduce its maintainability cost, which is generally more expensive then its development cost. http://jamesrdf.blogspot.com

I've been struggling with this too and it's causing debates at work. I'm with Scot, I've seen much JPA <-> JSF stuff with no middle tier to demarcate transations and common business boundaries. It does get tricky with versioning and naming, but writing the application as an API without assuming anything about UI layer or persistance layer still yields the best results in my opinion. It caters well to TDD and allows me to change from JSF to Wicket without much trouble.

For a desktop application, Java 6 penetration is not a problem: it is possible to release packages that will download Java 6 if needed (Launch4j in Windows and .deb packaging with dependencies in Linux). Actually blueMarine ships in that way since one year and I hadn't experienced problems.

Hey, is it a new blog? :-) You made a very good point, of course.

Hi Fabrizio, I don't think removing the data access layer from architecture design is a good idea. Think about testability and upcoming new technologies that definitively abstract from relational databases, such as cloud computing. http://mpetersen.tumblr.com/post/76648379/i-would-not-get-rid-of-the-dat...