Tuesday, February 28, 2006

Java Persistence - Towards a Generic DAO

Handling persistence from Java applications has possibly been one of the fiercely debated issues in all blogs today. With EJB 3.0 in the offing and already being implemented by some of the leading vendors like Oracle and JBoss, we are still debating on the usage of ORM vrs DAO. Until recently folks had been looking into ORM and DAO as competing approaches and preferred one over the other. Andy Grove has nicely laid out the pros and cons of the two approaches in his blog item.


A properly designed mid sized Java application should use both - ORM to set up the bridge between the OO application classes and the relational tables, with DAO to ensure a clean separation between the domain objects and the persistence layer. The DAO implementation provides the facades which the business/domain model uses, and enables a seamless switching of the persistence layer downstream. Hence whatever the size of the project, the DAO pattern offers one of the basic tenets of OO design - separation of concerns.


While the DAO offers a comfortable switch on the persistence/ORM layer underneath, the application can ensure a flexible DAO layer implementation by applying yet another level of indirection. Separate the abstraction from the implementation (aha! the Bridge), and you have a generic contract for your application to play with ..


public abstract class DAOBase<T extends DTOBase> {
private DAOImplBase<T> m_impl; // the underlying implementation
...
...


With the number of growing vendors offering you the best of the breed DAO solutions (BTW Firestorm from CodeFutures is really cool), this approach can give you the flexibility of switching your DAO implementation.

The application DAOs fit in the hierarchy on the abstraction side, while the various implementations (Firestorm, Hibernate etc.) subclass from the DAOImplBase.

// application DAO
public class EmployeeDAO<T extends DTOBase> extends DAOBase<T> {
...

// DAO implementation for JDBC
public class DAOJDBCImpl<T extends DTOBase> extends DAOImplBase<T> {
...


With the usual factories and utilities in place, finally the client code looks like the following:

// make the DAO
EmployeeDAO<Employee> e =
DAOFactory.getDAOFactory(DAOFactory.DAOImplType.JDBC).getEmployeeDAO();

// make the criteria
ICriteria cri = new SimpleCriteria("employee_id = 10");

// get 'em
List<Employee> es = e.read(cri, Employee.class);

No comments: