HibernateDaoSupport es una clase de Spring que faciilta las operaciones de acceso a datos con Hibernate mediante HibernateTemplate. A continuación, se muestra un diseño de un DAO genérico y su implementación.
Interfaz del DAO Genérico
package org.hibernate.dao.spring;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.hibernate.LockMode;
import org.springframework.dao.DataAccessException;
public interface DaoGenerico<T, ID extends Serializable> {
T cargarPorId(ID id) throws DataAccessException;
T obtenerPorId(ID id) throws DataAccessException;
boolean contieneEntidad(T entidad) throws DataAccessException;
void refrescar(T entidad, LockMode modo) throws DataAccessException;
void refrescar(T entidad) throws DataAccessException;
Serializable almacenar(T entidad) throws DataAccessException;
void almacenarOActualizar(T entidad) throws DataAccessException;
void almacenarOActualizarTodos(Collection<T> entidades) throws DataAccessException;
void modificar(T entidad, LockMode modo) throws DataAccessException;
void modificar(T entidad) throws DataAccessException;
void borrar(T entidad, LockMode modo) throws DataAccessException;
void borrar(T entidad) throws DataAccessException;
void borrarTodos(Collection<T> entidades) throws DataAccessException;
List<T> buscar(String consulta, Object valor) throws DataAccessException;
List<T> buscar(String consulta, Object[] valores) throws DataAccessException;
List<T> buscar(String consulta) throws DataAccessException;
List<T> obtenerTodos() throws DataAccessException;
List<T> buscarPorConsultaNombrada(String nombreConsulta) throws DataAccessException;
List<T> buscarPorConsultaNombrada(String nombreConsulta, Object valor) throws DataAccessException;
List<T> buscarPorConsultaNombrada(String nombreConsulta, Object[] valores) throws DataAccessException;
}
Clase de Implementación del DAO
package org.hibernate.dao.spring;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.LockMode;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@SuppressWarnings("unchecked")
public class DaoGenericoImpl<T, ID extends Serializable> extends HibernateDaoSupport implements DaoGenerico<T, ID> {
private final Log log = LogFactory.getLog(getClass());
private Class<T> tipoEntidad;
protected Class<T> obtenerTipoEntidad() {
if (tipoEntidad == null) {
ParameterizedType tipoGenero = (ParameterizedType) getClass().getGenericSuperclass();
tipoEntidad = (Class<T>) tipoGenero.getActualTypeArguments()[0];
log.debug("Tipo de entidad detectado: " + tipoEntidad.getName());
}
return tipoEntidad;
}
public void almacenarOActualizar(T entidad) throws DataAccessException {
getHibernateTemplate().saveOrUpdate(entidad);
}
public T cargarPorId(ID id) throws DataAccessException {
return (T) getHibernateTemplate().load(obtenerTipoEntidad(), id);
}
public T obtenerPorId(ID id) throws DataAccessException {
return (T) getHibernateTemplate().get(obtenerTipoEntidad(), id);
}
public boolean contieneEntidad(T entidad) throws DataAccessException {
return getHibernateTemplate().contains(entidad);
}
public void borrar(T entidad, LockMode modo) throws DataAccessException {
getHibernateTemplate().delete(entidad, modo);
}
public void borrar(T entidad) throws DataAccessException {
getHibernateTemplate().delete(entidad);
}
public void borrarTodos(Collection<T> entidades) throws DataAccessException {
getHibernateTemplate().deleteAll(entidades);
}
public List<T> buscar(String consulta, Object valor) throws DataAccessException {
return (List<T>) getHibernateTemplate().find(consulta, valor);
}
public List<T> buscar(String consulta, Object[] valores) throws DataAccessException {
return (List<T>) getHibernateTemplate().find(consulta, valores);
}
public List<T> buscar(String consulta) throws DataAccessException {
return (List<T>) getHibernateTemplate().find(consulta);
}
public void refrescar(T entidad, LockMode modo) throws DataAccessException {
getHibernateTemplate().refresh(entidad, modo);
}
public void refrescar(T entidad) throws DataAccessException {
getHibernateTemplate().refresh(entidad);
}
public Serializable almacenar(T entidad) throws DataAccessException {
return getHibernateTemplate().save(entidad);
}
public void almacenarOActualizarTodos(Collection<T> entidades) throws DataAccessException {
getHibernateTemplate().saveOrUpdateAll(entidades);
}
public void modificar(T entidad, LockMode modo) throws DataAccessException {
getHibernateTemplate().update(entidad, modo);
}
public void modificar(T entidad) throws DataAccessException {
getHibernateTemplate().update(entidad);
}
public List<T> obtenerTodos() throws DataAccessException {
return getHibernateTemplate().loadAll(obtenerTipoEntidad());
}
public List<T> buscarPorConsultaNombrada(String nombreConsulta) throws DataAccessException {
return getHibernateTemplate().findByNamedQuery(nombreConsulta);
}
public List<T> buscarPorConsultaNombrada(String nombreConsulta, Object valor) throws DataAccessException {
return getHibernateTemplate().findByNamedQuery(nombreConsulta, valor);
}
public List<T> buscarPorConsultaNombrada(String nombreConsulta, Object[] valores) throws DataAccessException {
return getHibernateTemplate().findByNamedQuery(nombreConsulta, valores);
}
}
Esta implementación permite reutilizar código común para operaciones CRUD y consultas en múltiples entidades, aprovechendo la inyección de dependencias de Spring.