Adam Bien's Weblog

Wednesday Aug 29, 2007

JPA/EJB3 killed the DAO

Regarding to the abstract of the DAO-Pattern: "Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation." the DAO tries to decouple the business logic from the proprietary resource. The solution to the problem is the following: "...The DataAccessObject is the primary object of this pattern. The DataAccessObject abstracts the underlying data access implementation for the BusinessObject to enable transparent access to the data source. The BusinessObject also delegates data load and store operations to the DataAccessObject..." [Core J2EE Patterns].

In the practise the DAO-Pattern was often realized by the following items:

  • DAO-Interface (provided a datasource-neutral interface)
  • DAO-Implementation (=access to the datasource implementation)
  • DAO-Factory (the creation of the implementation)
  • Optional: ServiceLocator (location of resources in JNDI)
The main problem in J2EE was the insufficient power of CMP 2.0. The limited query capabilities, no access to native SQL and lack of dynamic queries forced the developers to access the database using plain-JDBC. It was a very good idea to encapsulate the database access behind a replaceable and mockable implementation.
In EJB 3/Java EE 5 environment there is no need to use the low level JDBC to access the database any more. Actually you can use generic, but powerful Query Lanaguae, as well as Native SQL to fetch not only the persistent objects, but also data transfer objects and even primitive data types as well. It is even possible to execute update and delete statements. The JPA comes already with the EntityManager which provides already generic data access functionality. The usage cannot be simpler. The EntityManager will be just injected to the bean-class:

@Stateless
public class CustomerMgrBean implements CustomerMgr{

    @PersistenceContext
    private EntityManager em;

It's just one liner. The DAO pattern is actually no more interesting for general data access, but is still needed to access data from stored procedures, flat files etc. However the bean above can be considered as a "DAO", but very streamlined one...

Readers questions are also discussed in the "Data Access Object--Reader's Questions" post.

[See also an in-depth discussion in the "Real World Java EE Patterns--Rethinking Best Practices" book (Second Iteration, "Green Book"), page 259 in, chapter "Data Access Object"]

See you at Java EE Workshops at MUC Airport!


NEW: Java EE 7 Testing and Quality Workshop

A book about rethinking Java EE Patterns

Comments:

Hi adam nice post up to the point!I had a similar question a couple of months ago to Patrick Linskey, regarding DAO. I can see from your post that you define several notions of the DAO pattern, very true and very realistic (in various projects). From my experience though the DAO layer still there are cases that may introduce a think virtual layer but makes things nicer. My idea of DAO now days - trying to graspe the notion of EJB3 with an EJB2.0 mind is a SessionBean actually that will be dealing and exposing methods that will manipulate Entity Beans!

In small projects for sure this virtual thin layer is an overkill, though I think for larger projects that not only they make heavy use of sotred procedures but they introduce either complex HQL statements or related logic..maybe there is a place for this ...kind of SLSBs

It would be nice if you could share your thought regarding this DAO...implementation

Posted by Paris Apostolopoulos on August 29, 2007 at 04:53 PM CEST #

Hi,

I would like to point on a use case you seemed to miss where I think the DAO is mandatory:
--> when you do not have access to an orm to access your data, ie webservice or straight jdbc/file access.

Peace,

Posted by opensourcereader on August 29, 2007 at 05:25 PM CEST #

1.) It seems to me you just renamed CustomerDao to CustomerMgrBean (at least that's the way Seam does it)

"However the bean above can be considered as a "DAO", but very streamlined one..."

Well your're right in the first part, not in the second. Your bean still has a findCustomer() method I guess and you still have a Dao interface, it's just called CustomerMgr.

2.) If you want to exchange your implementation (to read from a file, from LDAP, ...) then you need the Dao. And you might not know when your customer wish to exchange some parts, so for the main business entities I guess it's good to keep the Daos around (and for user management etc).

3.) It's easier to test the application with Daos (yes I know about JMockit)

Peace
-stephan

--
Stephan Schmidt :: stephan@reposita.org
Reposita Open Source - Monitor your software development
http://www.reposita.org
Blog at http://stephan.reposita.org - No signal. No noise.

Posted by Stephan Schmidt on August 29, 2007 at 06:35 PM CEST #

Paris,

I don't like the small comment window :-) - I will write another post soon to clarify this issue,

regards,

Posted by Adam Bien on August 29, 2007 at 09:32 PM CEST #

Stephan,

1.) "It seems to me you just renamed CustomerDao to CustomerMgrBean (at least that's the way Seam does it)"

I didn't renamed it, I just collapsed two layers.

2.)"If you want to exchange your implementation (to read from a file, from LDAP, ...) then you need the Dao"
Absolutely. The question is: how often it really happens, and how often it happened. I have to admin: in the last 12 years in my work as consultant I never replaced a SQL-Database with something else :-).

3.) "It's easier to test the application with Daos (yes I know about JMockit)"

You can very easily replace the implementation of the bean as well. Changing either the annotation, or providing a XML-Descriptor.

Posted by Adam Bien on August 29, 2007 at 09:36 PM CEST #

Hi OpensourceReader,

"when you do not have access to an orm to access your data, ie webservice or straight jdbc/file access."

Yes. But then I would call this Pattern "Integration Service". In this particular case it would be still a Session Bean (why actually not? - think about monitoring etc.)

I will discuss your thought further in near future.

Pease, Love and Java EE 5/6 :-),

Posted by Adam Bien on August 29, 2007 at 09:41 PM CEST #

I disagree with your statement.

Why tangling data access logic with business logic, especially when you have to build not only simple queries (not talking about the simple CRUD operations)?
When it comes to readaybility, i want to 'see' my core business logic in first place, not worrying about the data access logic (only the WHAT, not the HOW).

Why bind your business services to a special technology? I rather wouldn't mix business logic with infrastructure / technology, even if the chance is very small to change technology, but keeping business logic free of any infrastructure (ok, this seems to be a little bit dogmatic ;o) but binding to a special technology fixes your business logic in a very hard way).

Why committing to EJB3 as the only way of realizing data access? I've seen many projects which used different data access 'strategies', as appropriate for their different problem areas.
Should those data access logic also remain directly in your service classes, too? Why not shielding such different strategies (or at least encapsulating it) for the different clients?

What's about DRY? Would you distribute your data access logic all over your services? Actually, you may call the same data access logic within more than one context within different services. A DAO seems to be a perfect place to factorize such logic.

Greetings

Mario

Posted by Mario Gleichmann on August 30, 2007 at 12:02 AM CEST #

Mario,

your comments are actually very good - we should meet us on a conference or so and discuss the issues in more detailed way. I tried to clarify the topic with my today's post: http://www.adam-bien.com/roller/page/abien?entry=to_layer_or_not_to
I'm already curious about your opinion.

I would say: it depends. It depends how complex your application really is.
"Why committing to EJB3 as the only way of realizing data access?"

Why not, it cannot be simpler :-)

"Should those data access logic also remain directly in your service classes, too?"

It depends, whether it is cohesive, or not.
If you need different strategies, you need variations. Now is the question how often you have to switch between them.

"What's about DRY?"

I thought, my solution is even drier, because the query resides in a single class. Nothing prevents you to access the service from another bean.

"A DAO seems to be a perfect place to factorize such logic."

Or a service like an EJB3 - it's simpler. Everything which I need is already inside every container. I do not need factories any more...

Do you like actually SOA? :-)

thank you very much for your detailed comment!,

regads,

Posted by Adam Bien on August 30, 2007 at 02:42 PM CEST #

"I didn't renamed it, I just collapsed two layers."

Before you had CustomerDAO and JpaCustomerDAO.

Now you have CustomerMgr and CustomerMgrBean.

I can't see any collapsing :-)

Peace
-stephan

Posted by Stephan Schmidt on August 30, 2007 at 02:42 PM CEST #

"Or a service like an EJB3 - it's simpler. Everything which I need is already inside every container. I do not need factories any more..."

I only used on factory ... Spring.

"Or a service like an EJB3 - it's simpler. Everything which I need is already inside every container. I do not need factories any more..."

You do not mix storage with business logic in your CustomerMgr, do you?

Peace
-stephan

Posted by Stephan Schmidt on August 30, 2007 at 02:46 PM CEST #

Stephan,

wait for EJB 3.1. Then I would be able to get rid of business interfaces :-).

thanks!,

Posted by Adam Bien on August 30, 2007 at 02:46 PM CEST #

Never get rid of interfaces ! :-)

Posted by Stephan Schmidt on August 30, 2007 at 04:40 PM CEST #

Might want to consider the testing advantages of having DAO classes separate from your service classes. When "bus logic" gets complicated, it is nice to be able to mock out the DAO, even when it IS provided by jpa/hibernate etc...

Posted by James Law on August 30, 2007 at 11:02 PM CEST #

Adam,

thanks for your answers - i will have a look at your newest post relating to the current topic...

Of course - like most design decisions - it's a matter of choosing the one or other side of a trade off. So you're right to say it depends - but you have to be clear about the consequences (which should be aligned with the projects qoals which should be also clear). And 'killing' the DAO comes with even the mentioned ones.

>> Why not, it cannot be simpler :-)

Hm, focussed on the API you are almost right. But i think we'll grab this issue again, when JPA offers an adequate Criteria API ;o)

>> It depends, whether it is cohesive, or not.

Even if it might be cohesive, you've introduced infrastructure code to your business services (in this case even more than one)
Beside the Introduction of technology to your core business logic, i think the main question is not about the notion or usage of a domain specific style according to the surrounding context of the business logic. It's rather about the question if you want to introduce i.e. more complex query building logic next to your business logik.

>> I thought, my solution is even drier, because the query resides in a single class. Nothing prevents you to access the service from another bean.
...
>> Or a service like an EJB3 - it's simpler

Now we entered a naming game. Like Stephan said - wether you call it xxxDAO or xxxMgr isn't relevant to the client. What stays relevant is the question, if your xxxMgr not only provides data access or manipulation logic but in addition to that business logik. Could that be a mix of two responsibilities (in the matter of responsibility as a reason to change - now you have different reasons/causes to change the service: the business logik could change or data access logic (maybe joining another table for an aggregation) could change)?

>> I do not need factories any more...

That depends of the infrastructure and / or the use of adequate design strategies like dependency injection: if you'll use Spring for example, you also won't be in need of an explicit factory. Of course you could say Spring's Application Context is now in the role of the factory - but than the EJB Container is a kind of factory, too

>> Do you like actually SOA? :-)

That's a really interessting question (and a tough one for me, too). I always wonder if going back to a pure procedural style of building systems is always the right one (of course i could also say 'it depends' ;o)).
It may be good for delivering core business services with the right kind of granularity (that's another question, worth of discussing), where you can strip off core business entities down to its pure data. But it always feels like violating TDA. The client only uses the data and have to derive / calculate additional information by himself (or delegating / 'orchestrating' it to another service).
Of course you could do 'SOA' in a more OO-way, i.e. in regard to SCA. But than i alway ask myself what's the difference to pure OO practiced in a 'right' way, except of introducing 'SOA-styles' of interaction.
Actually, i'm not sure about the real success keys of SOA (it's yet a mystery to me).

Greetings

Mario

Posted by Mario Gleichmann on August 31, 2007 at 01:11 AM CEST #

You could also stop posting this shit every day for a week on javablogs.com

Posted by 83.77.204.109 on August 31, 2007 at 09:14 AM CEST #

Actually,
A DAO can encapsulate data sources very much different from databases, like LDAP, xml files, text files... name your own.
As far as I know JPA is DB only for now.

Posted by Srgjan Srepfler on September 03, 2007 at 04:38 PM CEST #

DAO Pattern is like assembler. Like COBOL. It's a bureocratic thing that exists only becouse there are not good automatic tools to do the job: The modern compiler killed assembler, the RDBMS killed COBOL, and JPA and Linq are going to kill DAO. Automatic support to query and persistence on different scenarios could and should be a transversal concern, not part of the main solution. It just clutter models and packages... DAO is just plain wrong since the beginning

Posted by 189.32.65.74 on February 17, 2010 at 05:47 PM CET #

... Dao is so wrong that most people generates it automatically. It's a copy and paste pattern... DAO don't have a bad smell... it IS a bad smell.

Posted by Alex on February 17, 2010 at 05:50 PM CET #

with advent of many ORM like hibernate, DAO is getting obsolete now days.

Posted by Javin @ Java Enum Example on November 27, 2011 at 10:54 AM CET #

Hi Adam,

I'm a junior architect and I've read your blog for a while. I'm very interested in the way you rethink the business tier and I summarized the main bad/good arguments into this document: could you please tell me if I well understood you or if I missed some important points?
I also added some remaining questions to the document.
The next month, I will start a new (huge) JEE6 project and I mean to improve the business tier design, to make it leaner :)
By the way, if you like the lean philosophy, I recommend the book "The Toyota Way" (Liker) to you. As a Toyata Manager once said, lean is just common sense (why should I code this useless interface? ;) ).

Regards.
Glh

Posted by Glh on January 06, 2013 at 03:38 AM CET #

I forgot the url:

http://imageshack.us/photo/my-images/812/jee6ejb.png/

Regards.
Glh

Posted by Glh on January 08, 2013 at 01:08 AM CET #

@Glh,

your picture, as well as, most of the assumptions looks right. Minor improvements:

1. use @Inject instead of @EJBhttp://www.adam-bien.com/roller/abien/entry/inject_vs_ejb

2. Use CDI annotations instead of JSF

I will answer your questions in a dedicated blog post,

thanks for constructive questions!,

adam

Posted by Adam Bien on January 08, 2013 at 01:27 PM CET #

@Glh,

could you please extract your questions from the picture into a comment?

I would answer your interesting questions in one of my upcoming posts.

thanks!,

adam

Posted by Adam Bien on January 11, 2013 at 12:31 PM CET #

Sure, thank you for your consideration:

"Q1) If I have several services that use a common dao (to make a distinction between logic and data-access code):

=> is my dao still a DAO? (must I rename it otherwise?)
=> should I use CDI or EJB to manage my "DAO"? Indeed, the DAO doesn't contain the slightest logic and according to EJB3 specification: “An enterprise bean typically contains business logic”.
Moreover, the DAO will only be accessed from local EJBs; therefore the DAO should not need to benefit from all EJB services. Certainly, a lighter container-management would fit better a DAO, am I right?

Q2) From my experience, we store one type of data into only one data-store. It means that if someday we switch from one data-store to another one, we need to update the data-access code but we don't need to develop an interface (because there is always only one implementation). Am I right?

Q3: My last question is more related to JPA: JPQL is not able to persist every kind of data into any kkind of datastores (flat file etc..), it only works for SQL-databases but SQL is already a common langage. So from a provider-independence perspective; JPQL is useless, isn't it? It's just a myth, isn't it?"

Regards.

Guilhem

Posted by Glh on January 13, 2013 at 08:16 PM CET #

Hi Adam, could you please tell me when you mean to answer? Just to avoid me checking the post several times a week :)

Regards.
Glh

Posted by Glh on January 26, 2013 at 08:09 PM CET #

@Glh,

this is my common practice to improve the stats :-)

Checkout: http://www.adam-bien.com/roller/abien/entry/data_access_object_reader_s

thanks for preparing the questions!,

adam

Posted by Adam Bien on January 28, 2013 at 02:30 PM CET #

Should I avoid JPA to develop small to medium size modern webapplication and stick to traditional MVC pattern with or without DAOs (database portability is never required). Java EE server portability is required in future.

Posted by Sree Rama on April 22, 2013 at 03:45 PM CEST #

Your article and subject matter is thoughtful and also useful.
But I believe JPA could not kill DAO until Java EE6 platform is gets matured enough for modern web-application development (I notice that the ASP .Net is doing well over here).
We know that Java is still doing great in large enterprise applications with Hibernate or without hibernate.
I am developing CRUD webapp with JSF2.1, EJB3.1, Eclipselink JPA, NetBeans7.3. The application is small to medium with less than 10 users. I felt JDBC, DAO would be more productive and portable while the production environment is Tomcat 7.x.
I happened to change the design and persistence logic to make it Tomcat compatible. The lightweight EJB3.1 may not bring so called portability. With JPA2.2, I could not avoid native queries and hence not easily portable.
My journey with JPA,EJB3.1,JSF2.1, GlassFish 3.x while developing CRUD application was good. JPA as a specification is great and may be good for large applications unlike with DAOs. Writing queries with multiple joins from more than one table is not easy to learn for me and my team with java and .Net developers. With JPA, the learning curve may not be steep but definitely time consuming and I felt not much worth when native queries could not be avoided.
Hence I believe JPA is not matured well enough for modern web-applications.
Hello Adam Bien, Would you please provide good online or book references for Java EE 6 for developing modern webapplication using JSF,JPA,EJB & Glassfish webprofile.
And just started with the pdf copy of Apress - Pro JPA 2 Mastering the Java Persistence API (November 2009) . The books like Core Java Server Faces 3Rd Edition, and online references like coreservlets.com were not much useful without information from primefaces forum and comments from BalusC.

Posted by Sree Rama on April 22, 2013 at 03:50 PM CEST #

@Adam,
Would you please respond to my comments?

Posted by Sree Rama on April 29, 2013 at 05:48 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
Links
License