- The vendor of your database changes?
- You will have to replace your relational database with LDAP, flat files or object oriented storage?
- You will have to replace JPA with iBatis or even plain JDBC?
- You will have to replace your local storage with remote service calls?
The questions above are interesting and valid, but how likely is such a case? 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. In my past projects, only in (very) few cases we had to switch the database vendor.We never switched from a relational database to a flat file or LDAP. I guess it is unlikely in the future as well. Interestingly the real problem during the migration from one relational DB to another was not the leaky encapsulation of SQL statements or hiding classes behind interfaces, rather than different locking behavior, which just cannot be hidden or abstracted with Java-means. Most projects are concerned about the answers for the questions above and introduce DAOs, which are especially leaky by nature. Locking behavior is one thing, semantic behavior is even harder to abstract. A typical DAOs operates "per Value", whereby OR-tools work with managed / attached objects. If you start to emulate such a behavior for e.g. flat files, you will either fail, or eventually implement Hibernate 5.0.
My post "JPA/EJB 3 Killed The DAO" was not precise enough. In some situations even the classic DAOs are still a good solution, but for the vast majority of all cases and projects are absolutely not. If you are developing a product, like e.g. a CMS software, it is essential to be as flexible as possible to survive in a heterogenous market. A DAO could help you to abstract from the particular data source, but such abstractions are leaky by nature. The variations of different data sources is already predefined by the system requirements of your product. You have to protect your business logic from being dependent on the particular data store implementation. DAO can help you to abstract from the variations. Even so, in most commercial products a particular database tend to be better supported, than the other. Just look at the Hibernate, Toplink or openJPA support for a particular database.
In a usual projects there is no need to introduce a DAO as as standalone component. It is enough to rely on your common sense and try to remain DRY. Then you could easily use the EntityManager directly in your Service layer and if you notice some repetition or duplication just to refactor the code into one place. This can happens without any ceremony - you either delegate the calls to a class which encapsulates common queries, or you could even inherit such capabilities from a common class. You could call both strategies a "DAO" - in J2EE, however, you would start with a DAO in own layer, in Java EE a DAO can just evolve but is optional...
[see pages: 80, 141 and 261 in "Real World Java EE 6 - Rethinking Best Practices" book]