A melhor maneira que encontrei até agora foi esta, usando abstract dao generico que contem a funcionlidade de filtro.
public interface CRUD<T> {
/**
* Carrega o objeto da base de dados.
* @param id - id do objeto
* @return objeto<T> - resultado da pesquisa.
*/
public T load(Long id);
/**
* Atualiza ou cria um novo objeto na base de dados.
* @param obj - o objeto
* @return T - o objeto atualizado
* @throws DAOException - Se ocorreu algum erro ao fazer a chamada ao banco.
*/
public T save(T obj) throws DAOException;
/**
* Exclui o objeto da base de dados.
* @param obj - objeto a ser deletado
* @throws DAOException
*/
public void delete(T obj) throws DAOException;
/**
* Pesquisa na base de dados de acordo com os criterios de pesquisa do filtro.
* @param filtro
* @return a pesquisa.
*/
public List<T> find(Filter filtro);
/**
* Pesquisa na base de dados de acordo com os criterios de pesquisa do filtro.
* @param filtro
* @return a pesquisa.
*/
public T get(Filter filtro);
/**
* Lista todos os objetos encontrados na base de dados.
* @return
*/
public List<T> list();
/**
* Realiza uma contagem dos resultados encontrados para a pesquisa.
* @param filtro
* @return a quantidade de registros encontrados.
*/
public int count(final Filter filtro);
}
Depois eu crio uma classe abstrata que implementa o crud
public abstract class AbstractGenericDAO<T> implements CRUD<T>
private Class<T> persistentClass;
protected HibernateTemplate hibernateTemplate ;
@Autowired
public AbstractGenericDAO(Class<T> persistentClass, SessionFactory sessionFactory) {
super();
this.persistentClass = persistentClass;
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}
public T load(final Long id){
try{
return (T) hibernateTemplate.execute( new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = session.createCriteria(persistentClass);
criteria.add(Restrictions.eq("id",id));
return criteria.uniqueResult();
}
});
}catch(ObjectNotFoundException obf){
return null;
}
}
protected T update(T obj) throws DAOException{
try{
obj = (T) hibernateTemplate.merge(obj);
hibernateTemplate.flush();
return obj;
}catch(Exception e){
throw new DAOException("sua descricao do erro aqui",e);
}
}
protected T create(T obj) throws DAOException{
try{
hibernateTemplate.save(obj);
hibernateTemplate.flush();
return obj;
}catch(Exception e){
throw new DAOException("sua descricao do erro aqui",e);
}
}
@SuppressWarnings("unchecked")
public List<T> find(final Filter filter){
return hibernateTemplate.executeFind( new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = net.priuli.filter.utils.HibernateUtils.buildCriteria(filter, session, persistentClass);
return criteria.list();
}
});
}
@SuppressWarnings("unchecked")
public T get(Filter Filter){
List list = this.find(Filter);
return uniqueResult(list);
}
@Override
@SuppressWarnings("unchecked")
public List<T> find(final Map<String, Object> filter) {
return hibernateTemplate.executeFind( new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = net.priuli.filter.utils.HibernateUtils.buildCriteria(filter, session, persistentClass);
return criteria.list();
}
});
}
@Override
@SuppressWarnings("unchecked")
public T get(Map<String, Object> filtro) {
List list = this.find(filtro);
return uniqueResult(list);
}
@SuppressWarnings("unchecked")
public List<T> list() {
DetachedCriteria criteria = DetachedCriteria.forClass(persistentClass);
return hibernateTemplate.findByCriteria(criteria) ;
}
protected Session getSession(){
return SessionFactoryUtils.getSession(hibernateTemplate.getSessionFactory(), true);
}
protected T uniqueResult(List<T> list ){
if(list.size() > 0){
return list.get(0);
}else
return null;
}
}
com o dao generico não preciso fazer muito para ter as funcionalidade de filtro basta extender ela.
public interface ClienteDAO extends CRUD<Cliente>{
}
public class HibernateClienteDAO extends AbstractGenericDAO<Cliente> implements ClienteDAO{
@Autowired
public HibernateClienteDAO(SessionFactory sessionFactory) {
super(Cliente.class,sessionFactory);
}
@Override
public Cliente save(Cliente obj) throws DAOException {
if (obj.getId()==null){
return create(obj);
}else{
return update(obj);
}
}
}
Usando seria algo assim:
Filter filter = FactoryFilter.createFilter("nome","Felipe");
filter.addOrder(new Order("nome", Order.DESC));
//Buscando clientes que tenham nome like: 'Felipe%' (default) e ordenando DESC por nome"
List<Cliente> resultado = clienteDAO.find(filter);
ou assim:
Cliente cliente = new Cliente();
cliente.setNome("felipe");
Filter filter = net.priuli.filter.utils.ScannerHibernateEntity.parseRestrictions(cliente);
filter.addOrder(new Order("nome", Order.DESC));
//Buscando clientes que tenham nome like: 'Felipe%' (default) e ordenando DESC por nome"
List<Cliente> resultado = clienteDAO.find(filter);