Wednesday, August 22, 2007

Using DAO Design Pattern

DAO Pattern Definition

Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation.
Reference: Blue Prints

Introduction

When you are creating your application framework, you would like to persist your data using smart techniques, and I am not talking about Hibernate, JDO, OJB or anything else, however I can ask for you? Can your application support a storage system replacement without any problem? If your asnwer is NO, this text will be useful for you.

Define a Interface as foundation for DAOs

You can define a simple Interface, describing "WHAT" you would like to do, and not "HOW" to do. Getting this idea, we can to think in Interfaces usage. Take a look in the following code:

package framework.dao; 

import java.util.Collection;

public interface IGenericDAO {
public void save(Object object) throws DAOException;
public void update(Object object) throws DAOException;
public void remove(Object object) throws DAOException;
public Object findByPrimaryKey(Object pk) throws DAOException;
public Collection findAll() throws DAOException;
}

You can see that this interface can remind you the EJB EntityBeans model, if you are thinking it is correct! EntityBeans is a great idea, so We can continue using nice ideas(concepts) like that.
In fact, we are exposing that this interface says that It can save, update, remove or find results against Information storage.


We need a simple extension from java.lang.Exception called DAOException, which can be throwed by any method, its source can be as simple as in the following code section:

package framework.dao; 

public class DAOException extends Exception {
public DAOException(String message) {
super(message);
}
public DAOException(Throwable e) {
super(e);
}
}
The Implementation

We talked previouslly about smart codes, so we need to create and use it automaticlly and easier! You can have two choices:

  • Create a DAOFactory class
  • Use Spring Framework


DAOFactory

This class will implement a couple of patterns,as such:
Singleton - We will use one and just one instance and
Factory Method - The method returns always an interface, but in execution it will return a concrete class as wich implements this interface, in this case IGenericDAO.
See the following code for DAOFactory:

import java.io.IOException;
import java.util.Properties;

public class DAOFactory {

private static DAOFactory me = null;

private Properties props = null;

private DAOFactory() {
try {
props = new Properties();
props.load(DAOFactory.class.getResourceAsStream("daos.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}

public static DAOFactory getInstance() {
if (null == me) {
me = new DAOFactory();
}
return me;
}

public IGenericDAO getDAO(String name) {
IGenericDAO retorno = null;
try {
retorno = (IGenericDAO) Class.forName(props.getProperty(name))
.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return retorno;
}
}

The DAOFactory is using a properties file to discover the real implementations for DAOs that will be requested by applications.

You can create much better resource of reading, as such to auto-detect changes and update the properties in memory and other stuff.

Using Spring Framework

You can work with Dependency Injection, and you will use the context.xml used in all Spring Applications to describe this dependency.
Other nice Spring's feature is the ability to create DAOs implementations extends the HibernateDAOSupport class, which offer a lot of nice things to make your development easier.

This entry is to make you think that your applications can use dinamic configurations issues, and reduce the coupling between your layers, if you will use Spring or your own IoC framework, the most important is to use some useful DAO strategy as I this text is decribing (more information about DAO in Spring Framework - here).

7 Comments:

Anonymous said...

I think it'is worth using generics in your interface, allowing compilation type checking for your persistent objects

jorge báez said...

DAO pattern is a very straightforward design technique to build a persistence layer. You pointed very well the interface-implementation pair but i think you could improve the exception handling.

Avoiding the checked/unchecked issues, IMHO DAOException would make you write bad code soon.

While save, update and remove could throw an exception when no data is found, when database constraints,/keys are violated or when there is a real problem with the database, finder methods could throw it also when no data is found.

My approach is to use unchecked for save update and remove and to add a return element if needed (how many rows are updated/deleted) keys, constraints and so are enforced by the business logic. FindById returns an object and could throw an ElementNotFoundException to avoid return null and other finders just return a List or so. If no elements are found the list will be empty.

Check the spring framework and its database access exception hierarchy, it's really good.

Anonymous said...

This is Java right? Lose the I in your interface class names.

Here is a link to the Code Conventions for the JavaTM Programming Language http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html

Tech Per said...

I can only second that spring has this pretty much mapped out. You should take a look there.

I am all for RuntimeException type exceptions from a DAO layer. It was a mistake by Sun, to make the SQLException a checked exception. The code should be written in such a way, that IF they occur when the program is running, it is a real exceptional condition (like, the database is down, or your code tried to break a constraint). These are conditions, that your code cannot catch and do anything sane about, that suddenly make the method work again.

We really often do use exceptions the wrong way. They are ment for exceptional conditions only. Not as goto-like constructs.

Hence, I find it much better to let a "Model findByXxx(...)" method return null, if not found. It is not an exceptional condition, that an instance is not found.

mario.gleichmann said...

hm, there are some comments i'd like to give:

1.
I've never seen an interface that's declaring the HOW and not the WHAT so far ;o)

2.
As said before, you could use Generics, avoiding Typecasts at Runtime

3. I don't see any advantage of using a GenericDao Interface, since you won't use polymorphism on your DAO instances, right?

It may be far more usefull having a generic implementation of the core functionality - but if you look at Hibernates Session or EJB 3 EntityManager, you'll find that all the basic CRUD Methods are already there.

Greetings

Mario

Anonymous said...

Unfortunately the dao pattern is hopelessly broken. Why? Because today's persistence technologies leak horribly across these kinds of layers.

A few small examples:

When using JPA/Hibernate-like transparent persistence technologies it is not necessary to call dao.update() because it is handled transparently. Thus when switching a HibernateDao for a JdbcDao you will have a very hard time getting it to work right away.

Another point is the lazy-loading in JPA/Hibernate-like technologies. parent.getChildren() can be loaded lazily and transparently via hibernate, but good luck getting that to work when you use ibatis/jdbc like dao implementations.

Anonymous said...

Your suggestions helped me. Thanks...