views:

147

answers:

2

Assuming the DAO structure and component interaction described below, how should DAOs be used with persistence layers like hibernate and toplink? What methods should/shouldn't they contain?

Would it be bad practice to move the code from the DAO directly to the service?

For example, let's say that for every model we have a DAO (that may or may not implement a base interface) that looks something like the following:

public class BasicDao<T> {
 public List<T> list() { ... }
 public <T> retrieve() { ... }
 public void save() { ... }
 public void delete() { ... }
}

Component interaction pattern is --

service > DAO > model

A: 

IMHO there is no method the DAO "should" contain in general. It should contain exactly those methods your application needs. This may differ from model to model.

In Hibernate and JPA, methods like save and retrieve are "trivial" operations provided by the session / entity manager, so I don't see much point in adding them to the DAO, apart from maybe insulating the service / business logic from the actual persistence implementation. However, JPA is already an insulation in itself.

Moving persistence code directly into the service layer would bundle the two together. In a small app this might be OK, but over time even small apps tend to grow, and maintenance becomes an issue. Keeping separate concerns separated helps keep the code clean, thus easier to understand, extend and reuse.

Péter Török
+1  A: 

We found (as have others) that it was straightforward to write a generic DAO as a thin shim on top of the JPA calls.

Many were simply right on top of the JPA. For example, early on we simply had:

public <T> T update(T object) {
    return em.merge(object);
}

But the benefit of having the layer is that your layer is extensible, whereas the EM is not.

Later we added an overload:

public Thing update(Thing object) {
    // do magic thing processing
}

So, our layer was basically intact, but could handle custom processing.

For example, later, since early JPA didn't have Orphan processing, we added that in our backend service.

Even simple common DAO has value, simply as an abstraction point.

We just didn't need to make one for every group of objects (CustomerDAO, OrderDAO, etc.) like the olden days.

Will Hartung