I found JPA, or alike, don't encourage DAO pattern

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.


Solution 1:

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.

Solution 2:

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.

Solution 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.