An interesting debate about JPA and the DAO
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:
- code tends automatically to be tidier and more readable (see some of the Scot's examples);
- 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;
- 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.