developerWork: Don't Repeat the DAO
I am happy to see others express positive opinions about universal DAO interfaces in Java. Per Mellqvist writes in developerWorks: “Don’t Repeat the DAO” about creating a GenericDao interface:
public interface GenericDao <T, PK extends Serializable> {
/** Persist the newInstance object into database */
PK create(T newInstance);
/** Retrieve an object that was previously persisted to the database using
* the indicated id as primary key
*/
T read(PK id);
/** Save changes made to a persistent object. */
void update(T transientObject);
/** Remove an object from persistent storage in the database */
void delete(T persistentObject);
}
With the exception that we’re not using generics (instead, we cast… sigh), we’ve been using the same approach successfully for two years. We use the concept of Specification objects for search methods. Per Mellqvist prefers an approach where he extends the interface with finders:
public interface PersonDao extends GenericDao {
List<Person> findByName(String name);
}
He then imprements a FinderIntroductionInterceptor to execute the query. This is an interesting approach (although I personally find it very XML-heavy. XML-heavy is bad)
I would like to see this approach extended with test classes to test the correctness of the GenericDAO implementation, similarly to my article on Unit testing Hibernate mappings. Roughly I’d like to:
- create and read an object and check that the objects is equal to the retrieved object
- create, update and read an object and check that the saved object is equal to the retrieved object
- create, delete and read and check that retrive returns null (?)
- create a set of objects, and check that find returns the correct subset
Most of this can be done easily, but there are two issues: 1. The first level cache. “reads” will not actuall hit the underlying datasource, so the tests will trivially pass. 2. Handling test datasets for find-tests can be pretty hard to do in an elegant way.