Problema ao Usar DAO Genérico

Olá pessoal, estou com um problema ao tentar usar um DAO genérico, quando tento usar um DAOFactory.
Não obtenho mensagens de erro, mas também não salva nada no banco.

Esta é a entidade Cliente, a qual persisto.:

package br.com.siscolorimetry.dominio;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "cliente")
public class Cliente implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	private Long id;

	@Column(name = "nome")
	private String nome;

	@Column(name = "situacao")
	private boolean situacao;

	@Column(name = "tipo")
	@Enumerated(EnumType.STRING)
	private String tipo;

	@Column(name = "cpf")
	private String cpf;

	@Column(name = "rg")
	private String rg;

	@Column(name = "endereco")
	private String endereco;

	@Column(name = "bairro")
	private String bairro;

	@Column(name = "cep")
	private String cep;

	@Column(name = "cidade")
	private String cidade;

	@Column(name = "estado")
	private String estado;

	@Column(name = "tel_res")
	private String telRes;

	@Column(name = "tel_com")
	private String telCom;

	@Column(name = "tel_cel")
	private String telCel;

	@Column(name = "email")
	private String email;

	@Column(name = "refe1")
	private String refe1;

	@Column(name = "refe2")
	private String refe2;

	@Column(name = "refe3")
	private String refe3;

	@Column(name = "observacao")
	private String observacao;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public boolean isSituacao() {
		return situacao;
	}

	public void setSituacao(boolean situacao) {
		this.situacao = situacao;
	}

	public String getTipo() {
		return tipo;
	}

	public void setTipo(String tipo) {
		this.tipo = tipo;
	}

	public String getCpf() {
		return cpf;
	}

	public void setCpf(String cpf) {
		this.cpf = cpf;
	}

	public String getRg() {
		return rg;
	}

	public void setRg(String rg) {
		this.rg = rg;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public String getBairro() {
		return bairro;
	}

	public void setBairro(String bairro) {
		this.bairro = bairro;
	}

	public String getCep() {
		return cep;
	}

	public void setCep(String cep) {
		this.cep = cep;
	}

	public String getCidade() {
		return cidade;
	}

	public void setCidade(String cidade) {
		this.cidade = cidade;
	}

	public String getEstado() {
		return estado;
	}

	public void setEstado(String estado) {
		this.estado = estado;
	}

	public String getTelRes() {
		return telRes;
	}

	public void setTelRes(String telRes) {
		this.telRes = telRes;
	}

	public String getTelCom() {
		return telCom;
	}

	public void setTelCom(String telCom) {
		this.telCom = telCom;
	}

	public String getTelCel() {
		return telCel;
	}

	public void setTelCel(String telCel) {
		this.telCel = telCel;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getRefe1() {
		return refe1;
	}

	public void setRefe1(String refe1) {
		this.refe1 = refe1;
	}

	public String getRefe2() {
		return refe2;
	}

	public void setRefe2(String refe2) {
		this.refe2 = refe2;
	}

	public String getRefe3() {
		return refe3;
	}

	public void setRefe3(String refe3) {
		this.refe3 = refe3;
	}

	public String getObservacao() {
		return observacao;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Cliente other = (Cliente) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}

Uso este DAO Genérico

package br.com.siscolorimetry.dao.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Session;

import br.com.siscolorimetry.dao.GenericDAO;

public class HibernateGenericDAO<T> implements GenericDAO<T> {
	private Class<T> persistentClass;
	private Session session;

	@SuppressWarnings("unchecked")
	public HibernateGenericDAO(Session session) {
		this.session = session;
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public Session getSession() {
		return this.session;
	}

	@SuppressWarnings("unchecked")
	@Override
	public T pesquisaPorID(Serializable id) {
		return (T) this.session.get(this.persistentClass, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> ListarTodos() {
		return this.session.createCriteria(this.persistentClass).list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public T salvar(T entidade) {
		return (T) this.session.merge(entidade);
	}

	@Override
	public void excluir(T entidade) {
		this.session.delete(entidade);
	}

}

Para usar as transações, tento, sem sucesso usar esta Classe

package br.com.siscolorimetry.dao.hibernate;

import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.siscolorimetry.dao.ClienteDAO;
import br.com.siscolorimetry.dao.DAOFactory;
import br.com.siscolorimetry.util.HibernateUtil;

public class HibernateDAOFactory extends DAOFactory {
	private Session session;
	private Transaction tx;

	public HibernateDAOFactory() {
		this.session = HibernateUtil.getSession();
	}

	@Override
	public void cancelarTransacao() {
		this.tx.rollback();
		this.tx = null;

	}

	@Override
	public void iniciarTransacao() {
		this.tx = this.session.beginTransaction();
	}

	@Override
	public void encerrar() {
		if (this.tx != null) {
			this.tx.commit();
		}
		this.session.close();
	}

	@Override
	public ClienteDAO getClienteDAO() {
		return new HibernateClienteDAO(this.session);
	}

}

A interface DAOFactory

package br.com.siscolorimetry.dao;

import br.com.siscolorimetry.dao.hibernate.HibernateDAOFactory;

public abstract class DAOFactory {
	public static DAOFactory getDAOFactory() {
		return new HibernateDAOFactory();
	}

	public abstract void iniciarTransacao();

	public abstract void cancelarTransacao();

	public abstract void encerrar();

	public abstract ClienteDAO getClienteDAO();

}

Esta é a minha service.


package br.com.siscolorimetry.negocio;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;

import br.com.siscolorimetry.dao.ClienteDAO;
import br.com.siscolorimetry.dao.DAOFactory;
import br.com.siscolorimetry.dominio.Cliente;
import br.com.siscolorimetry.util.HibernateUtil;

public class ClienteService {
	public Cliente pesquisarPorId(Long id) {
		Session session = HibernateUtil.getSession();
		try {
			return (Cliente) session.get(Cliente.class, id);
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Cliente> listarTodos() {
		Session session = HibernateUtil.getSession();
		try {
			return session.createCriteria(Cliente.class)
					.addOrder(Order.asc("nome")).list();
		} finally {
			session.close();
		}
	}

	public Cliente salvar(Cliente cliente) {

		DAOFactory daoFactory = DAOFactory.getDAOFactory();
		ClienteDAO clienteDAO = daoFactory.getClienteDAO();
		cliente = clienteDAO.salvar(cliente);
		daoFactory.encerrar();
		return cliente;

//FUNCIONA SE USAR ISSO AQUI EMBAIXO, MAS NÃO FUNCIONA SE USAR O DAOFACTORY NÃO TENHO SUCESSO


		// Session session = HibernateUtil.getSession();
		// Transaction tx = session.beginTransaction();
		// session.saveOrUpdate(cliente);
		// tx.commit();
		// session.close();
	}

	public void excluir(Cliente cliente) {
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		session.delete(cliente);
		tx.commit();
		session.close();
	}
}

Como assim não funciona?
você chegou a depurar? ou ver se ele executa alguma query?

Tente executar seu código com a propriedade show_sql setada para true no seu persistence.xml

E tome cuidado pra ver se não está engolindo nenhuma exceção

Não Rodrigo, não executa nenhunha query.
Mas sim, cheguei a debugar.

Por que você não invocou iniciarTransacao?

E por que no método do seu DAO genérico você usa o merge ao invés do saveOrUpdate que usa nos outros lugares?

Cara acho um pouco inflexível a utilização de DAO genérico não seria melhor você dedicar uma classe de DAO
para cada situação. Será que você está conectado realmente como você configurou o Hibernate?

Diego, se usar :

DAOFactory daoFactory = DAOFactory.getDAOFactory(); ClienteDAO clienteDAO = daoFactory.getClienteDAO(); cliente = clienteDAO.salvar(cliente); daoFactory.encerrar();

Não tenho resultado, mas se usar:

Session session = HibernateUtil.getSession(); Transaction tx = session.beginTransaction(); session.saveOrUpdate(cliente); tx.commit(); session.close();
Diretamente na classe, consigo persistir, o que sugere que a conexão esteja o.k., mas há um problema com meu aplicativo em algum lugar.

testou invocar iniciarTransacao?

Bem, Rodrigo, usando o inicarTransação funcionou, muito obrigado.

Você entendeu o motivo, né? :slight_smile:

esse monte de classes, distribuídos em um arquitetura do tipo bolo, é para:

a) estudo;
b) saber implementar alguns patterns e anti-patterns;
c) framework de persistência multi-flexível/expansível;

?

Para estudo, Felipe.