Arquitetura de persistencia utilizando Hibernate

0 respostas
Spool

Boa tarde!

Estou com algumas duvidas relacionadas a arquitetura de persistência utilizando o hibernate. Me deem uma forcinha!!!

Supondo que eu possua o cenario:

Meu cadastro de usuarios esta em um pacote;
Meu cadastro de produtos esta em outro pacote;
Minha camada de persistencia esta em ainda outro;

* Onde digo pacote, leia-se .jar, biblioteca, módulo

Na minnha estrutura do pacote de Usuarios, eu tenho os DAO´s que estendem uma interface(CRUD) generico que esta dentro do pacote de persistencia.
Porem, nenhuma implementacao relacionada a persistencia em si esta dentro do pacote de usuarios.
A mesma coisa acontece dentro do pacote de produtos, DAO´s que implementam a mesma interface, mas sem nenhuma implementacao.

A minha duvida eh a seguinte:
Como monto uma camada de persistencia autonoma que lide apenas com a interface dos DAO´s de qualquer que seja o módulo solicitando a persistencia?

Bom, ate o momento, a chamada aos metodos do DAO, estao funcionando, porem, eu nao tenho nenhum controle sobre a transacao dentro do pacote Usuario, por exemplo. Mesmo sabendo que o controle da transacao nao seria incumbencia do pacote de usuarios, eu necessito do controle nesse ponto pois:
Existem sistuações onde eu teria que incluir muitos usuarios de uma vez, (processo batch) e do jeito q esta atualmente, o commit eh realizado registro a registro, o que impacta profundamente na performance da camada de persistencia.

Gostaria de alguma sugestao nesse respeito.
Estou colocando abaixo algumas classes de controle da camada de persistencia.

A proposito, todos os modulos serao utilizados dentro ou fora de um container (ou seja, podem rodar na WEB ou em um desktop). Vi comentarios sugerindo a utilizacao de spring para controlar as transacoes, porem, nao sei se funciona adequadamente em ambientes fora de um appserver. Me deem opinioes sobre isso tb, por favor.

Seguem as classes:

GenericDAO
public interface GenericDAO<T, ID extends Serializable> {

	T salvar(T entity);

	T atualizar(T entity);

	void excluir(T entity);

	T pesquisarPorID(ID id);

	List<T> pesquisarTodos();

}
DAOFactory
public abstract class DAOFactory {

	public static final Class HIBERNATE = br.com.factory.HibernateDAOFactory.class;

	public static DAOFactory instance(Class factory) {

		try {
			return (DAOFactory) factory.newInstance();
		} catch (Exception ex) {
			throw new RuntimeException("Couldn't create DAOFactory: " + factory);
		}
	}

	public abstract UsuarioDAO getUsuarioDAO();

}
HibernateDAOFactory
public class HibernateDAOFactory
		extends DAOFactory {

	@Override
	public UsuarioDAO getUsuarioDAO() {

		return (UsuarioDAO) instantiateDAO(UsuarioDAOHibernate.class);
	}

	private GenericHibernateDAO instantiateDAO(Class daoClass) {

		try {
			GenericHibernateDAO dao = (GenericHibernateDAO) daoClass.newInstance();
			dao.setSession(getCurrentSession());
			return dao;
		} catch (Exception ex) {
			throw new RuntimeException("Can not instantiate DAO: " + daoClass, ex);
		}
	}

	protected Session getCurrentSession() {

		return HibernateUtil.getSessionFactory().openSession();
	}

	public static class UsuarioDAOHibernate
			extends GenericHibernateDAO<Usuario, Long> implements UsuarioDAO {

		@Override
		public Usuario atualizar(Usuario entity) {

			return super.update(entity);
		}

		@Override
		public void excluir(Usuario entity) {

			super.delete(entity);
		}

		@Override
		public Usuario pesquisarPorID(Long id) {

			return super.findById(id, false);
		}

		@Override
		public List<Usuario> pesquisarTodos() {

			// TODO
			return super.findByCriteria();
		}

		@Override
		public Usuario salvar(Usuario entity) {

			return super.save(entity);
		}

	}

}
GenericHibernateDAO
public abstract class GenericHibernateDAO<T, ID extends Serializable> {

	private Class<T> persistentClass;

	private Session session;

	public GenericHibernateDAO() {

		this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public void setSession(Session s) {

		this.session = s;
	}

	protected Session getSession() {

		if (session == null) {
			throw new IllegalStateException("Session has not been set on DAO before usage");
		}
		return session;
	}

	public Class<T> getPersistentClass() {

		return persistentClass;
	}

	public T findById(ID id, boolean lock) {

		T entity;
		if (lock) {
			entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
		} else {
			entity = (T) getSession().load(getPersistentClass(), id);
		}
		return entity;
	}

	public T save(T entity) {

		getSession().save(entity);
		return entity;
	}

	public T update(T entity) {

		getSession().update(entity);
		return entity;
	}

	public void delete(T entity) {

		getSession().delete(entity);
	}

	public void flush() {

		getSession().flush();
	}

	public void clear() {

		getSession().clear();
	}

	protected List<T> findByCriteria(Criterion... criterion) {

		Criteria crit = getSession().createCriteria(getPersistentClass());
		for (Criterion c : criterion) {
			crit.add(c);
		}
		return crit.list();
	}

}

Resumidamente, é isso!
Aguardo sugestões.

Desde já agradeço.

Criado 28 de agosto de 2009
Respostas 0
Participantes 1