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:
GenericDAOpublic 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();
}
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();
}
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);
}
}
}
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.