42

I found JPA, or alike, don't encourage DAO pattern. I don't know, but I feel like that, especially with server managed JTA managers.

After adequate hands-on using DAO pattern, I started designing JPA based application around that pattern. But it doesn't fit in, IMO. I tend to lose quite a features of JPA and all.

Well, suppose you fire a query with pessimistic locking and it returned a list of entites from a DAO method. Upon returning, transaction ends and lock is gone (a case with server managed JTA manager). So, no point, loosely speaking. There are valid cases, though.

Another example is much more trivial. Suppose you fire a query to get some entity, that has a lazy loading one-to-many association with some other entity. Upon returning the DAO method, transaction ends. Lazy loading wouldn't work anymore, you simply get null or something. To cope with that we load it eagerly manually. we do something like a.getBList().size().

Thus, IMO its better to not make a DAO exclusively, and do it in your business bean, this way you will be able to take advantage of those useful features. Or ORM API can be considered a DAO/Data-layer itself, arguably. So, we don't need to make another.

What you folks think about it?

Note: I don't say, by any means, that the DAO pattern is obsolete. Indeed it depends case to case.

Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133

3 Answers3

48

For simple applications, I don't see any problem in using the EntityManager directly from EJBs and skipping the DAO pattern (I'm tired of writing too much code). And my feeling is indeed that this is what JPA and the Java EE API encourage. But it may still be justified for more complex applications (for data access from stored procedure, flat files...). So you are right, it depends :)

You'll find some other enlightened point of views in Has JPA Killed the DAO? on InfoQ but you won't be surprised by the content and the conclusion that can be summarized as: you don't really need the DAO pattern anymore for standard data access, you may however need it for some more complex situations, but we live better without it.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • (+1) I tend to agree that if one doesn't have anything particular in mind, there is not a reason to create a dao layer. Even a generic DAO, let alone a separate DAO class for entity. – Bozho Jan 20 '10 at 10:56
  • I have been struggling with finding a good way to test my Java EE JAX-RS/JPA code, and it's been a nightmare trying to get a workable "container-in-the-tests" solution. The main aspect is trying to inject a @ Context PersistenceContext from the tests. I'm thinking that using @ EJB Dao along with a constructor that's called from tests and sets the Dao will be clean. – Matthew Cornell Aug 20 '12 at 16:24
34

If you don't define the DAO itself to be transactional, you won't have those problems.

The service layer is supposed to be transactional, because a transaction is supposed to span multiple operations. Putting each insert/update in a transaction is not the best scenario.

With spring you achieve that very easily. Without it you perhaps include the transaction logic in your DAO again - i.e. dao.beginTransaction() and dao.commitTransaction() and use that from the service layer instead.

As I understand, you suggest that using the EntityManager directly in the service classes is probably better than having a wrapper DAO class. I don't agree for one reason. Working the DAO class (interface at best) in your service classes, you don't have dependency on the JPA API at all. You don't have to construct Query objects or the likes. This might not turn out to be a great advantage, but you'd agree it is a best practice. And you can later switch to plain JDBC, plain-text, XML, or whatever, by only changing the DAO.

This, although used widely as an example of why you should abstract something in another layer, is most often simply an overdesign. But sometimes the fact that all your database access operations are going through one place means you can add logging, access-level checks, etc. (Yes, sometimes the DAO is not a particularly suitable way to do this).

So ultimately, to return to your point - it depends.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Thanks, Bozho. I found transaction logic depends on business rule. If we make our DAO to adhere with that, means we are polluting it with business rule. If we don't it means we need to take the data provided by DAO, and do things in business logic. Latter case, will have the problem of lazy-loading, what I mentioned earlier. Moreover, see this post http://stackoverflow.com/questions/1748238/pros-and-cons-of-the-use-of-dao-pattern/1748282#1748282 – Adeel Ansari Jan 20 '10 at 09:23
  • I see your edits. Yes, Spring with Hibernate/JPA is good here to work with. Cent percent agreement. But my emphasis on server managed JTA transactions, where you don't have the liberty of getting transaction. – Adeel Ansari Jan 20 '10 at 09:26
  • 7
    *"Working the DAO class (...) in your service classes, you don't have dependency on the JPA API at all."* Ok, if you don't do this you're dependent on EJB 3 - but so what? Seriously, what is the problem? I don't care being dependent on a standard API. – Pascal Thivent Jan 20 '10 at 09:44
  • 3
    sure, you are still dependent on that bacause you use it, and there's no problem in that. But my point was that you could easily change the persistence mechanism without modifying all your classes, because they depend only on the DAO interface. – Bozho Jan 20 '10 at 09:48
  • 9
    @Bozho I perfectly get your point but I've not seen that happen very frequently in 10 years and consider this event as a kind of myth. – Pascal Thivent Jan 20 '10 at 10:26
  • 1
    +1, aboslutely true. DAO pattern is still relevant even in JPA environment, because your service layer is transactional and one transaction can span multiple DAO calls. – semberal Jan 20 '10 at 10:32
  • 1
    me neighter :) but it's also possible to add logging, access checks, etc. Now the DAO is not the best place to do that. So ultimately - it depends :) – Bozho Jan 20 '10 at 10:33
  • @semberal I'm not following you. What's the problem of a stateless session bean using the entity manager from a transactional point of view? – Pascal Thivent Jan 20 '10 at 10:45
  • From transactional point of view? Nothing. But I see problems from architectural point of view. You service layer is polluted with relatively low-level data access. – semberal Jan 20 '10 at 11:30
  • @Bozho I am really curios: when working with a DB, what kind of code can one have in a DAO? Access checks: that is not the responsibility of DAO, is it? Logging - AspectJ solves that problem. Some other things? – V G Dec 02 '13 at 16:44
  • DB queries is the typical case. You should not write entityManager.createQuery(..) in your service layer – Bozho Dec 05 '13 at 07:13
  • I'm just learning design patterns. These are not only a lot and very complex by themselves, but everyone and their grandma give different explanations on why does one need / need not to use a DAO as a separate layer. On top of that there are a lot of explanations all over the internet using all sorts of frameworks, and this is easily the most sensible explanation I have read. It rules them all. Before reading this I frequently questioned myself: "I don't need Spring, Do I? It's sort of like having the medicine without knowing what the illness is". Awesome explanation. – ibelcomputing Apr 23 '15 at 21:35
  • Too bad five years later SO labels these kinds of questions as not constructive and / or primarily opinion based. – ibelcomputing Apr 23 '15 at 21:38
3

DAO is used for design perspective, while JPA is some "Official" wrapper for data access functions. There's no way JPA is trying to kill DAO -- it can make DAO easier to implement, perhaps so easy that DAO looks so simple that it can be ignored. But without the DAO layer, the design benefit no longer exists.

Of course, for "simple" projects, it can be ignored. Many things can be "ignored" if the project is "simple" enough.

Elton
  • 149
  • 4
  • Elton: I totally agree on what you mean, without any if and but. However, I would like to emphasise that layering is not the only mean to get good design. Therefore, I can't agree on this statement of yours in its absolute sense, "without the layer means all the design benefit no longer exists". I hope you are getting my point. – Adeel Ansari Jan 26 '12 at 03:39
  • Ok. Dao layer exists for long time for reasons. It does bring design benefits. Without dao layer thosee design benefits are surely gone. Maybe in your situation you don't care that's why you feel it's obsolete. I think your question is actually about what dao brings, but whether you need what dao brings. To me the "Dao" layer never gone. when you inject EntityManager to your business tier, your business tier is doing job of Dao layer too. You combine those layers together for your reason. That could be better solution for your cases. Again and again, it depends, no "absolute" – Elton Jan 26 '12 at 11:13
  • Elton: Please notice that even before you arrived here the conclusion was the same, which was "it depends". I never felt that DAO is an obsolete pattern, please read the question carefully. I tried to make that point very very obvious. – Adeel Ansari Jan 27 '12 at 02:08
  • Yeah, the reason I add my comment was to append one more point, JPA is functional, and DAO is design perspective. Although I did not say "depends" explicitly, I was saying "depends" in another way. I wasn't against anyone, I think. – Elton Jan 27 '12 at 06:22
  • 1
    +1 for referring to a DAO architecturally as a wrapper. DAOs are a layer which wrap API which interface with a database. This might be JPA (EntityManager) with some ORM benefits and may well just be JDBC. – 8bitjunkie Dec 14 '12 at 23:11