Implementacao de DAO Generico e Heranca

4 respostas
P

Pessoal,

Estou aqui no site pesquisando sobre DAO Generico e me deparei com uma dúvida.

Primeiramente, tenho as classes:

class Pessoa {
	//atributos
}

class PessoaFisica extends Pessoa {
	//atributos
}

class PessoaJuridica extends Pessoa {
	//atributos
}

E tenho meu GenericDAO feito conforme já discutido varias vezes aqui:

public interface GenericDAO<T, PK extends Serializable> {
    public Class getObjectClass();
	public T save(T object);
	public T load(PK primaryKey);
    public T get(PK primaryKey);
	public List listAll();
	public List findByExample(final T example);
	public T findOneByExample(final T example);
	public List listAll(final int first,final int max);
	public int listAllPageCount();
	public List findByExample(final T example,final int first,final int max);
	public int findByExamplePageCount(final T example);
    public void update(T object);
    public void delete(T object);
    public void rebind(T object);
}

ai tenho a problematica da herança:

class PessoaDAO extends GenericDAO<Pessoa, Integer>() {}

class PessoaFisicaDAO extends PessoaDAO() {
	//metodos especificos
}

class PessoaJuridicaDAO extends PessoaDAO() {
	//metodos especificos
}

Por fim, para usar, seria algo como:

PessoaDAO pDAO = DAOFactory.getInstance().getDAO(PessoaDAO.class);
Pessoa p = new Pessoa();
pDAO.save(p);

Até aqui tudo bem, pois o generics me retornaria uma pessoa e os metodos do GenericDAO estariam aptos a receber Pessoa.

Contudo, se eu precisasse atualizar PessoaFisica ?

PessoaFisicaDAO pfDAO = DAOFactory.getInstance().getDAO(PessoaFisicaDAO.class);
PessoaFisica pf = new PessoaFisica();
pfDAO.save(pf);

o Metodo save estaria esperando uma Pessoa e não PessoaFisica.

Alguém sabe como resolver isso?

Grato

4 Respostas

D

Eu jogaria um generics na classe Pessoa também.

class PessoaDAO<P> extends GenericDAO<Pessoa, Integer>() {}  

class PessoaFisicaDAO extends PessoaDAO<PessoaFisica>() {  
    //metodos especificos  
}
R
class PessoaDAO extends GenericDAO<T extends Pessoa, Integer>

Ou seja, PessoaDAO é um GenericDAO para qualquer classe que estenda Pessoa.

P

rmendes08:
class PessoaDAO extends GenericDAO<T extends Pessoa, Integer>

Ou seja, PessoaDAO é um GenericDAO para qualquer classe que estenda Pessoa.

Certo, neste caso, a implementacao seria?

caso 1:

PessoaDAO<Pessoa> pDAO = DAOFactory.getInstance().getDAO(PessoaDAO.class);
Pessoa p = new Pessoa();
pDAO.save(p);

caso 2:

PessoaFisicaDAO<PessoaFisica> pfDAO = DAOFactory.getInstance().getDAO(PessoaFisicaDAO.class);
PessoaFisica pf = new PessoaFisica();
pfDAO.save(pf);

Certo?

No caso, se for por ioc, da pra fazer com esses generics?

grato

H
public class Dao<T extends Entidade> {

	private Class<T> classeEntidade;
	private EntityManager entityManagerFilho;
	private EntityManagerFactory entityManagerFactoryFilho;

	/**
	 * 
	 * @return EntityManager
	 */
	protected EntityManager getEntityManager() {
		if (entityManagerFilho == null) {
			try {
				@SuppressWarnings("rawtypes")
				Class clazz = this.getClass();

				Field field = clazz.getDeclaredField("entityManagerFactory");
				field.setAccessible(true);
				entityManagerFactoryFilho = (EntityManagerFactory) field.get(this);

				if (entityManagerFactoryFilho == null) {
					Field fieldEntity = clazz.getDeclaredField("entityManager");
					fieldEntity.setAccessible(true);
					entityManagerFilho = (EntityManager) fieldEntity.get(this);
				} else {
					entityManagerFilho = entityManagerFactoryFilho.createEntityManager();
				}
				return entityManagerFilho;
			} catch (Exception e) {
				throw new ExcecaoProcessamentoSistema("Não foi possível encontrar a propridade entitymanager/entityManagerFactory para o dao " + this.getClass().getCanonicalName());
			}
		} else {
			return entityManagerFilho;
		}
	}

	/**
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected Class<T> getClasseEntidade() {
		if (classeEntidade == null) {
			@SuppressWarnings("rawtypes")
			Class classeDaoCorrente = this.getClass();
			if (classeDaoCorrente == null) {
				throw new ExcecaoProcessamentoSistema("Não foi possível identificar a classe da entidade no dao.");
			}
			ParameterizedType genericsClasseDaoCorrente = (ParameterizedType) classeDaoCorrente.getGenericSuperclass();
			if (genericsClasseDaoCorrente == null) {
				throw new ExcecaoProcessamentoSistema("Não foi possível identificar o generics da classe da entidade no dao.");
			}

			Type[] tiposDoGeneric = genericsClasseDaoCorrente.getActualTypeArguments();
			if (tiposDoGeneric == null) {
				throw new ExcecaoProcessamentoSistema("Não foi possível identificar o generics da classe da entidade no dao.");
			}

			if (tiposDoGeneric.length < 1) {
				throw new ExcecaoProcessamentoSistema("O generics da classe da entidade no dao  nao foi inicializado.");
			}

			classeEntidade = (Class<T>) tiposDoGeneric[0];
		}
		return classeEntidade;
	}

	/**
	 * 
	 * @param id
	 * @return
	 */
	public T buscar(Serializable id) {
		return getEntityManager().find(classeEntidade, id);
	}

	/**
	 * 
	 * @param entidade
	 */
	public void registrar(T entidade) {
		getEntityManager().merge(entidade);
	}

	/**
	 * 
	 * @param entidade
	 */
	public void armazenar(T entidade) {
		getEntityManager().persist(entidade);
	}

	/**
	 * 
	 * @param entidade
	 */
	public void remover(T entidade) {
		getEntityManager().remove(entidade);
	}

	/**
	 * 
	 * @param id
	 */
	public void remover(Serializable id) {
		Entidade entidade = buscar(id);
		getEntityManager().remove(entidade);
	}

	public void flush() {
		getEntityManager().flush();
	}

	@SuppressWarnings("unchecked")
	public List<T> buscarTodos() {
		NamedQuery namedQuery = getQueryBuscarTodos(classeEntidade);
		Query query = null;
		if (namedQuery == null) {
			String newQuery = "FROM ".concat(classeEntidade.getSimpleName());
			query = getEntityManager().createQuery(newQuery);
		} else {
			query = getEntityManager().createNamedQuery(namedQuery.name());
		}

		return query.getResultList();
	}

	/**
	 * 
	 * @param classe
	 * @return
	 */
	private NamedQuery getQueryBuscarTodos(Class<?> clazz) {
		NamedQueries namedQueries = (NamedQueries) clazz.getAnnotation(NamedQueries.class);
		if (namedQueries != null) {
			for (NamedQuery namedQuery : namedQueries.value()) {
				if (namedQuery.name().equalsIgnoreCase(clazz.getSimpleName() + ".buscarTodos")) {
					return namedQuery;
				}
			}
		}
		return null;
	}

	/**
	 * 
	 * @param nomeQuery
	 * @param parametros
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> buscarQueryPorNome(String nomeQuery, Object... parametros) {
		Query query = getEntityManager().createNamedQuery(nomeQuery);
		if ((parametros != null) && (parametros.length > 0)) {
			for (int i = 0; i < parametros.length; ++i) {
				query.setParameter(i + 1, parametros[i]);
			}
		}
		return query.getResultList();
	}

	/**
	 * 
	 * @param nomeQuery
	 * @param parametros
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> buscarQueryPorNome(String nomeQuery, Map<String, Object> parametros) {
		Query query = getEntityManager().createNamedQuery(nomeQuery);

		for (String key : parametros.keySet()) {
			query.setParameter(key, parametros.get(key));
		}
		return query.getResultList();

	}

	/**
	 * 
	 * @param nomeQuery
	 * @param parametros
	 * @return
	 */
	public Integer executarAteracao(String nomeQuery, Object... parametros) {
		Query query = getEntityManager().createNamedQuery(nomeQuery);
		if ((parametros != null) && (parametros.length > 0)) {
			for (int i = 0; i < parametros.length; ++i) {
				query.setParameter(i, parametros[i]);
			}
		}
		return Integer.valueOf(query.executeUpdate());
	}
}
@Stateless
public class PessoaDAO extends Dao<Pessoa> {
	@PersistenceContext(unitName = "pu1")
	private EntityManager entityManager;

}
@Stateless
public class PessoaFisicaDAO extends Dao<PessoaFisica> {
	@SuppressWarnings("unused")
	@PersistenceContext(unitName = "pu1")
	private EntityManager entityManager;

}
@Stateless
public class PessoaJuridicaDAO extends Dao<PessoaJuridica> {
	@PersistenceContext(unitName = "pu1")
	private EntityManager entityManager;

}
Criado 18 de maio de 2011
Ultima resposta 18 de mai. de 2011
Respostas 4
Participantes 4