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...
You will find some examples in p4j5 - feel free to participate.


[my tweets]  Rss My book: Real World Java EE - Rethinking Best Practices

Kommentare:

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

Gesendet von Paris Apostolopoulos am August 29, 2007 at 02: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,

Gesendet von opensourcereader am August 29, 2007 at 03: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.

Gesendet von Stephan Schmidt am August 29, 2007 at 04:35 PM CEST #

Paris,

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

regards,

Gesendet von Adam Bien am August 29, 2007 at 07: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.

Gesendet von Adam Bien am August 29, 2007 at 07: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 :-),

Gesendet von Adam Bien am August 29, 2007 at 07: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

Gesendet von Mario Gleichmann am August 29, 2007 at 10:02 PM 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,

Gesendet von Adam Bien am August 30, 2007 at 12: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

Gesendet von Stephan Schmidt am August 30, 2007 at 12: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

Gesendet von Stephan Schmidt am August 30, 2007 at 12:46 PM CEST #

Stephan,

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

thanks!,

Gesendet von Adam Bien am August 30, 2007 at 12:46 PM CEST #

Never get rid of interfaces ! :-)

Gesendet von Stephan Schmidt am August 30, 2007 at 02: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...

Gesendet von James Law am August 30, 2007 at 09: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

Gesendet von Mario Gleichmann am August 30, 2007 at 11:11 PM CEST #

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

Gesendet von 83.77.204.109 am August 31, 2007 at 07: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.

Gesendet von Srgjan Srepfler am September 03, 2007 at 02:38 PM CEST #

Senden Sie einen Kommentar:
  • HTML Syntax: Ausgeschaltet
Interviews/About
My Recent Book
Java One 2009
CommunityOne East N.Y.C
JavaONE 2008 Interview
Search
...the last 150 posts
...the last 10 comments
greenfire.dev.java.net
Links
my.netbeans.org
Visitors
License