Vamos discutir sobre DAOs genericos!

26 respostas
fredferrao

Pessoal andei pesquisando por ae sobre daos genericos, e não gostei muito do que vi, ou nao entendi muito bem.

Bom o exemplo em questão é este que colo aqui:
Feito pelo ralphsilver neste tópico: http://www.guj.com.br/posts/list/140871.java

Minha idéia de dao generico é que ele seja generico e faça tudo pra mim, com qualquer tipo de object que eu envie pra ele.
Então nao poderiamos parar no BaseDaoImpl???

Porque é que eu preciso ir alem e ter mais uma interface e uma classe por ex: PessoaDao e PessoaDaoImpl??

Estou enferrujado e nao estou entendendo este conceito.

E outra imaginem eu com um CRUD de 100 Entities, neste caso vou precisar criar + 100 interfaces Dao e + 100 classes DaoImpl, fala sério 300 arquivos sendo que poderiam ser 100 e o BaseDaoImpl dar conta de fazer qualquer coisa com eles?? Na verdade este BaseDaoImpl ja consegue fazer tudo, o que nao entendo é porque ter mais uma interface e uma classe para cada entity.

Alguem tem uma outra versão de Daos genericos ai pra oferecer??

import java.util.List;

public interface BaseDAO<T> {
	/*
	 * Ações possíveis feita com CRUD. Os métodos cujos parâmetros
	 * são do tipo java.util.List, são enviados em massa, ou seja,
	 * os dados são processados e armazenados e apenas no final o 
	 * aplicativo lança o commit. Para grande massa de dados é mais
	 * viável pois o tempo de processo é muito maior quando abre apenas
	 * uma conexão e aplica apenas uma ação de persistencia
	 * */
	public T remove(T object) throws Exception;
	public T persist(T object) throws Exception;
	public T update(T object) throws Exception;
	
	public List<T> update(List<T> object) throws Exception;
	public List<T> persist(List<T> list) throws Exception;
	public List<T> remove(List<T> object) throws Exception;
	/*
	 * Aqui se aplica todos os tipos de buscas possível para se fazer
	 * dentro de uma aplicação padrão.
	 * */
	public List<T> findAll() throws Exception;
	
	public T load(Object obj) throws Exception;
}

classe abstrata DAOImpl:

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import br.edu.unianhanguera.plt.dao.BaseDAO;

public abstract class BaseDAOImpl<T> implements BaseDAO<T> {
	protected EntityManager em = null;
		
	@Override
	public abstract List<T> findAll() throws Exception;
	@Override
	public abstract T load(Object obj) throws Exception;

	@Override
	public T persist(T object) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			em.persist(object);
			transaction.commit();
			return object;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

	@Override
	public List<T> persist(List<T> list) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			for(T object:list)
				em.persist(object);
			transaction.commit();
			return list;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

	@Override
	public T remove(T object) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			em.remove(object);
			transaction.commit();
			return object;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

	@Override
	public List<T> remove(List<T> list) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			for(T object:list)
				em.remove(object);
			transaction.commit();
			return list;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

	@Override
	public T update(T object) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			em.merge(object);
			transaction.commit();
			return object;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

	@Override
	public List<T> update(List<T> list) throws Exception {
		EntityTransaction transaction = em.getTransaction();
		transaction.begin();
		try{
			for(T object:list)
				em.merge(object);
			transaction.commit();
			return list;	
		}catch(Exception e){
			transaction.rollback();
			throw e;
		}
	}

}

quando eu preciso criar uma classe (Pessoa por exemplo) eu a interface DAO:

public interface PessoaDAO extend BaseDAO<PessoaEntity>{}

e o DAOImpl

public interface PessoaDAOImpl extends BaseDAOImpl<PessoaEntity> implements PessoaDAO{}

26 Respostas

Paulo_Silveira

ola Fred. Excelente pergunta! Algumas opinioes minhas:

  • para 300 classes de modelo, voce nao precisa de 300 DAOs: voce pode (e deve) agrupar os que fizerem sentido.
  • nao pegue catch em Exception: o elhor é fazer o tratamento correto de PersistenceException e deixar um finally bem escrito
  • cuidado com as transacoes : é melhor deixar o controla transacional fora, pois ai voce pode agrupar operacoes do dao. caso contrario voce tera problemas para criar uma transacao que insira dois tipos de objetos diferentes, por exemplo
  • eu hoje em dia ja nao gosto de dao generico, ainda mais para usar com heranca: traz muita dor de cabeca, e se voce for ver, sem esse codigo transacional, ele resolve pouca coisa. e a melhor maneira sempre é compor em vez de herdar!

abracos

marcos1EM

Quanto ao fato de criar cada uma classe DAO para cada entidade não tem como fugir,mas realmente não faz sentido ter uma interface para cada entidade, então apenas não a implemente.

romarcio

Nesse caso que vc postou, não bastaria fazer assim:

Não sei se precisa criar uma interface para Pessoa, acho de mais.

fredferrao

Paulo Silveira:
ola Fred. Excelente pergunta! Algumas opinioes minhas:

  • para 300 classes de modelo, voce nao precisa de 300 DAOs: voce pode (e deve) agrupar os que fizerem sentido.
  • nao pegue catch em Exception: o elhor é fazer o tratamento correto de PersistenceException e deixar um finally bem escrito
  • cuidado com as transacoes : é melhor deixar o controla transacional fora, pois ai voce pode agrupar operacoes do dao. caso contrario voce tera problemas para criar uma transacao que insira dois tipos de objetos diferentes, por exemplo
  • eu hoje em dia ja nao gosto de dao generico, ainda mais para usar com heranca: traz muita dor de cabeca, e se voce for ver, sem esse codigo transacional, ele resolve pouca coisa. e a melhor maneira sempre é compor em vez de herdar!

abracos

Opa Paulo blz.

Então, sobre as exceptions e etc no exemplo postado, apenas copiei e colei do outro topico para sevir de base a pergunta, este não é de fato o meu codigo, ainda estou atraz de respostas :smiley: Mas seus conselhos estão anotados.

Aproveitando sua presença no topico, estou justamento começando um projeto com vRaptor, e estou atraz da opção mais elegante e menos trabalhosa para a camada de persistencia, tirando proveito da injeção de dependencia, interceptors e tudo mais que o vRaptor tem a oferecer.

Certo, então sobre o exemplo citado voce acha que eu deveria parar no BaseDaoImpl, e então fazer daos para certos grupos de entities, seria isto?

E ainda sobre compor ai inves de herdar, me corriga se entendi seu ponto errado, eu teria então o BaseDaoImpl concreto, e um outro tipo de dao ± assim:

public class ExemploDao {
   private BaseDaoImpl baseDao;

   public RHDao(BaseDao baseDao)
      this.baseDao = baseDao;
   }
}
...

E ainda por ultimo, voce diz que não gosta de dao generico, qual seria sua abordagem para a persistencia hoje em dia, é disto que estou atras, de uma abordagem mais contemporania, usando o que a OO e o vRaptor tem a nos oferecer.

Grato.

fredferrao

romarcio:
Nesse caso que vc postou, não bastaria fazer assim:

Não sei se precisa criar uma interface para Pessoa, acho de mais.

Ao meu ver sim, mas mesmo neste exemplo eu ainda teria 100 classes modelos e outras 100 dao, claro que as operações basicas ja estariam prontas.

Porem é justamente isto que estou tentando entender, em minhas pesquisas no google, a maioria dos exemplos que encontro estão sempre deste jeito, queria saber o porque. Sera que um cara fez uma vez e o resto saiu copiando e postando :shock: :shock: :lol: :lol:

romarcio

fredferrao:
romarcio:
Nesse caso que vc postou, não bastaria fazer assim:

Não sei se precisa criar uma interface para Pessoa, acho de mais.

Ao meu ver sim, mas mesmo neste exemplo eu ainda teria 100 classes modelos e outras 100 dao, claro que as operações basicas ja estariam prontas.

Porem é justamente isto que estou tentando entender, em minhas pesquisas no google, a maioria dos exemplos que encontro estão sempre deste jeito, queria saber o porque. Sera que um cara fez uma vez e o resto saiu copiando e postando :shock: :shock: :lol: :lol:

Sim, mas disso acho que vc nem deve tentar fugir, pq é a Orientação Objetos.

A classe PessoaEntity, seria apenas a entidade com getters, setters e a classe PessoaDAO teria outra função que seria a realização das consultas e tudo mais envolvendo banco de dados.
O padrão é não mistura-las mesmo.

juliofsn

Criar as interfaces e DAO’s para cada entidade geralmente é feito para se ganhar flexibilidade.

Se você usa o mesmo DAO genérico para todas as entidades, está assumindo que a persistência será igual para todas as entidades, o que nem sempre é verdade.

Em algum momento você pode querer tratar especificidades de cada entidade, e se tudo estiver desacoplado desde o início isso se torna mais fácil, principalmente se você estiver tratando com uma quantidade grande de entidades como você especulou.

Se o problema for escrever tantos arquivos, bom, se você tem o seu ambiente, não custa nada perder alguns minutos criando um pequeno gerador de código pra isso.

fredferrao

romarcio:
fredferrao:
romarcio:
Nesse caso que vc postou, não bastaria fazer assim:

Não sei se precisa criar uma interface para Pessoa, acho de mais.

Ao meu ver sim, mas mesmo neste exemplo eu ainda teria 100 classes modelos e outras 100 dao, claro que as operações basicas ja estariam prontas.

Porem é justamente isto que estou tentando entender, em minhas pesquisas no google, a maioria dos exemplos que encontro estão sempre deste jeito, queria saber o porque. Sera que um cara fez uma vez e o resto saiu copiando e postando :shock: :shock: :lol: :lol:

Sim, mas disso acho que vc nem deve tentar fugir, pq é a Orientação Objetos.

A classe PessoaEntity, seria apenas a entidade com getters, setters e a classe PessoaDAO teria outra função que seria a realização das consultas e tudo mais envolvendo banco de dados.
O padrão é não mistura-las mesmo.

Com certeza voce esta certo, PessoaEntity é a classe burra com getters e setters e jpa annotation, nao foi isto que quis dizer.

Eu esta pensando em algo como DaoGenericoParaQualquerEntity + PessoaEntity, ClienteEntity, CidadeEntity, etc, quando digo economizar é disto que estou falando, fazer apenas um DAO que sirva a todos.

fredferrao

juliofsn:
Criar as interfaces e DAO’s para cada entidade geralmente é feito para se ganhar flexibilidade.

Se você usa o mesmo DAO genérico para todas as entidades, está assumindo que a persistência será igual para todas as entidades, o que nem sempre é verdade.

Em algum momento você pode querer tratar especificidades de cada entidade, e se tudo estiver desacoplado desde o início isso se torna mais fácil, principalmente se você estiver tratando com uma quantidade grande de entidades como você especulou.

Se o problema for escrever tantos arquivos, bom, se você tem o seu ambiente, não custa nada perder alguns minutos criando um pequeno gerador de código pra isso.

Sim, eu pensei nisso. Mas neste caso eu faria apenas se fosse necessario, não? Se um ou outro precisasse de tratamento especial ai sim caberia uma herança e tals.

juliofsn

fredferrao:
Se um ou outro precisasse de tratamento especial ai sim caberia uma herança e tals.

Mas aí, imagine se você tiver que tratar a classe Pessoa, você teria que criar o DAO para Pessoa e na camada acima, mudar a classe que utiliza o DAO genérico para fazer operações com Pessoa, trocando pelo DAO específico que você criou.

Se você já tem um DAO para cada entidade, você só teria que mudar o DAO de Pessoa.

fredferrao

juliofsn:

Mas aí, imagine se você tiver que tratar a classe Pessoa, você teria que criar o DAO para Pessoa e na camada acima, mudar a classe que utiliza o DAO genérico para fazer operações com Pessoa, trocando pelo DAO específico que você criou.

Se você já tem um DAO para cada entidade, você só teria que mudar o DAO de Pessoa.

Realmente, se houverem novos metodos que o “controller” por exemplo teria que chamar, ia ter que sair refatorando, mas se os metodos continuam os mesmos e mudou apenas a logica do “persist” por exemplo, o polimorfismo daria conta do recado.

fantomas

Oi fredFerrao,

Estou entendendo que o ponto que está gerando as dúvidas é o fato de que o DAO está diretamente ligado adiferenciado de banco de dados e que o “DAO generico” na verdade precisa “saber” qual é o TIPO de objeto que será persistido, ou seja, na verdade talvez não tenha nada de generico assim, já que ele precisa saber os tipos dos objetos.

A interface específica de cada entidade acaba fazendo parte do padrão de solução (DAO), caso vc tenha mais de um tipo de banco de dados vc “força” que a implementação seja garantida seguindo a especificação da interface.

Resumindo…infelizmente a coisa envolve muito código, acredito que o uso de um bd orientado a objetos estas coisas desapareçam completamente.

P.S Desculpem se não entendi direito o tópico.

flws

fredferrao

fantomas:
Oi fredFerrao,

Estou entendendo que o ponto que está gerando as dúvidas é o fato de que o DAO está diretamente ligado adiferenciado de banco de dados e que o “DAO generico” na verdade precisa “saber” qual é o TIPO de objeto que será persistido, ou seja, na verdade talvez não tenha nada de generico assim, já que ele precisa saber os tipos dos objetos.

A interface específica de cada entidade acaba fazendo parte do padrão de solução (DAO), caso vc tenha mais de um tipo de banco de dados vc “força” que a implementação seja garantida seguindo a especificação da interface.

Resumindo…infelizmente a coisa envolve muito código, acredito que o uso de um bd orientado a objetos estas coisas desapareçam completamente.

P.S Desculpem se não entendi direito o tópico.

flws

O que estavamos discutindo, é a necessidade dos dois ultimos, ex: PessoaDao e PessoaDaoImpl, que como voce disse acaba fazendo parte da solucao(DAO).

Sobre os bancos de dados especificos, creio que não entram no mérito da discussão, pois levando-se em conta que se esta usando JPA, não haverá implementações especificas para cada BD.

fantomas

Entendi…

Acredito que ao utilizar a JPA você tenha condições de eliminar ao menos a interface (PessoaDao) porem a classe PessoaDaoImpl (teriamos que mudar o nome dela) teria que continuar por causa do tipo da entidade que teriamos que informar ao mecanismo ORM ( entityManager.find(objectClass, id) ) sem falar do local dos algoritmos de manipulação dos objetos especificos daquela entidade.

Outro detalhe em relação a interface é que: se voce estiver utilizando o spring será sempre aconselhado a utilizar uma interface ao invés de uma implementação ao desenvolver suas classes e descreve-las nos seus (do spring) xmls.

flws

juliofsn

fantomas:
Entendi…

Acredito que ao utilizar a JPA você tenha condições de eliminar ao menos a interface (PessoaDao) porem a classe PessoaDaoImpl (teriamos que mudar o nome dela) teria que continuar por causa do tipo da entidade que teriamos que informar ao mecanismo ORM ( entityManager.find(objectClass, id) ) sem falar do local dos algoritmos de manipulação dos objetos especificos daquela entidade.

Outro detalhe em relação a interface é que: se voce estiver utilizando o spring será sempre aconselhado a utilizar uma interface ao invés de uma implementação ao desenvolver suas classes e descreve-las nos seus (do spring) xmls.

flws

Não é apenas para o Spring, usar a interface garante desacoplamento mesmo se por exemplo, você não puder usar a JPA nessa entidade em específico, por exemplo, se você divide os dados em vários bancos e certas entidades estiverem em SGBD’s que não têm suporte para JPA, ou se os dados de alguma entidade forem obtidos/manipulados através de serviços web (imagine uma aplicação que faça uso da API de redes sociais como o Twitter).
Existe chance de você precisar de toda essa flexibilidade?
Bom aí é muito de cada um, mas eu acho que é sempre melhor ser o mais correto possível desde o começo.

C

Opa, estou com o mesmo problema do nosso colega fredferrao.
Vamos lá.
Tenho implementado o seguinte:
Pessoa (entity com geters e seters da tabela)
Dao Generico

import java.io.Serializable;
import java.util.List;
import java.util.Map;
public interface DaoGenerico<T, ID extends Serializable> {	
	public Class<T> getObjectClass();
	public T save(T object);
	public T searchById(ID id) throws Exception;
	public T update(T object);
	public void delete(T object);
	public List<T> retrieve();
	public List<T> searchByParam(String query, Map<String, Object> params);
	public List<T> searchByParam(String query, Map<String, Object> params, int maximo, int atual);
	public List<T> searchPesq(String query);
	public T searchPesq(String query, Map<String, Object> params);
}

Tenho criado também meu DaoGenericoImp

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

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import br.com.xxx.dao.DaoGenerico;

@Transactional(readOnly=true, propagation=Propagation.REQUIRED)
public class DaoGenericoImp <T, ID extends Serializable> implements DaoGenerico<T, ID>{

	private EntityManager entityManager;
	private final Class<T> oClass;
	
	public Class<T> getObjectClass(){
		return this.oClass;
	}
	
	@PersistenceContext
	public void setEntityManager(EntityManager em){
		this.entityManager = em;
	}
	
	protected EntityManager getEntityManager(){
		if(entityManager == null)
			throw new IllegalStateException("Erro #1");
		return entityManager;		
	}
	
	@SuppressWarnings("unchecked")
	public DaoGenericoImp(){
		this.oClass = (Class<T>)
		((ParameterizedType)getClass().getGenericSuperclass()).
							getActualTypeArguments()[0];
	}
	
	@Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	public T update(T object){
		getEntityManager().merge(object);
		return object;		
	}
	
	@Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	public void delete(T object){
		object = getEntityManager().merge(object);
		getEntityManager().remove(object);
	}
}

Após crio um interface para a Pessoa

import br.com.xxx.dao.DaoGenerico;
import br.com.xxx.entities.Pessoas
public interface IPessoas extends DaoGenerico<Pessoas, Integer> {

}

Crio também a PessoasImp

import br.com.xxx.entities.Pessoas
import br.com.xxx.interfaces.IPessoas;

public class PessoasDaoImp extends DaoGenericoImp<Pessoas, Integer> implements
		IPessoas {

}

E por fim meus beans PessoasMB que é neste ponto onde estou querendo chegar.
Bom toda a implentação dos meus beans tenho que fazer quase sempre a mesma coisa, por exemplo:
Tenho em todos eles os metodos save, delete, cancel, edit
Neste caso estava querendo criar alguma coisa generica tipo implementar estes metodos apenas uma unica vez e sempre que criar um novo bean estes metodos já estariam prontos, caso eu fosse querer fazer alguma coisa a mais ai sim implementava o metodo com estas novos coisas a mais.

Exemplo:
PessoasMB

private Pessoas pessoa;
	
@Resource
private DaoGenerico<Pessoas, Integer> pessoasDao;

public String edit() {
	Pessoas ag = getFromEdit();
	setPessoas(ag);
	return "";
}

public String delete() {
	Pessoas ag = getFromEdit();
	pessoasDao.delete(ag);
	cancel();
	return "";
}

O bean seria mais ou menos isto, claro com mais coisas implementadas, porém todo o bean que implementar tenho que fazer sempre isto, no caso fica muito código redundante.

Alguem pode me dar umas dicas de como posso fazer ou o que fazer para melhorar?

fredferrao

No teu caso voce esta querendo fazer um ManagedBean generico certo?

Não sei se seria possivel, teria que ver se o JSF faria o trabalho, pq ele que vai instanciar este MB generico.

Só testando, tu pode seguir a mesma logica do DaoGenerico.

lelodois

Não curto DAO genérico… e acredito que os dãos devem ser agrupados e não independentes das entidades, ou seja,
ao invés de:

UserDao
   RuleDao
   CategoryDao

Usaria:

AdministrationDao

Depois volto e leio o tópico inteiro para dar continuidade, agora estou sem paciência :slight_smile:
rs
Abraços…

fredferrao
lelodois:
Não curto DAO genérico... e acredito que os dãos devem ser agrupados e não independentes das entidades, ou seja, ao invés de:
UserDao
   RuleDao
   CategoryDao

Usaria:
[code]
AdministrationDao
[code]

Depois volto e leio o tópico inteiro para dar continuidade, agora estou sem paciência :)
rs
Abraços...


Legal, o Paulo Silveira tinha dito sobre agrupar, mas sumiu do tópico :roll:

Volta ai, e se possivel poste um exemplo de como voce faz os seus DAOS.

Valeu.

mario.fts

Eu to acompanhando o tópico pra ver as sugestões, esses daos genéricos tbm não me agradam na totalidade, simplemente pq tenho q cirar uma classe pra cada dao, emsmo sem ter nenhum método específico.

Usar composição seria interessante, o Vraptor teria algum jeito de fazer algo do tipo:

public class ClienteController{

ClienteController(Dao<Cliente> daoCliente){
...
}
...
}

se alguém tiver um exemplo…

fredferrao

mario.fts:
Eu to acompanhando o tópico pra ver as sugestões, esses daos genéricos tbm não me agradam na totalidade, simplemente pq tenho q cirar uma classe pra cada dao, emsmo sem ter nenhum método específico.

Usar composição seria interessante, o Vraptor teria algum jeito de fazer algo do tipo:

public class ClienteController{

ClienteController(Dao<Cliente> daoCliente){
...
}
...
}

se alguém tiver um exemplo…

É exatamente nisto que estou pensando, em usar composição, e tambem estou usando o vRaptor.

Estive lendo o exemplo de composição do Effective Java, Josh Bloch, e estava pensando em adapta-lo para Daos,
ficaria ± assim:

public class BaseDao<T> implements Dao<T> //este BaseDao faria as operações basicas de CRUD aplicavel a todas as entities

a partir dai usar composição para daos espeficicos, não saquei muito bem a necessidade do “ForwardingDao” que teria que criar seguindo o exemplo do livro, ainda estou vendo

E ainda teria que como ficaria a DI do vRaptor, como vc citou.

Thiago_Senna

não li o tópico todo, mas deixa eu alfinetar:

eu não gosto de DAO caso esteja utilizando algum framework de persistência. Para CRUD uso logo os métodos Session.xxx() ou entityManager.xxx(). Vc pode encapsular eles em uma classe sua como PersistenceManager, por exemplo. Já as Queries, vc pode colocar em objetos próprios. Por exemplo:

Usuario u = PersistenceMng.queryFirst(new ObterUsuarioPorLoginESenha("thiago", "1234");

List<Prova> provas = PersistenceManager.queryAll(new ObterProvasPorAlunoEAno(u, 2010));

É um exemplo básico - mas a partir daí é só explorar a idéia e melhorá-la.

mario.fts

To com preguiça de dar quote… :lol:

Thiago Senna:

Eu tbm gosto dessa idéia , mas apenas para sistemas muito simples. Eu tive uma situação onde um processo em específico precisava ser feito em jdbc direto, por conta da performance, e tive q reescrever um monte de classes por não ter a persistencia encapsulada dentro de um Dao. A idéia do dao genérico deveria ser essa mesma, funcionar como um entitymanager.

[EDIT] se bem que vendo sua implementação, ela seria mais um dao genérico que usar o entitymanager direto to certo? [/EDIT]

fredferrao:

Sim, é nisso mesmo q eu tava pensando. no caso, o exemplo foi infeliz, o certo seria injetar o dao genérico no dao específico, caso fossem necessárias operações específicas. caso não tivesse essa necessidade, poderia injetar o dao normal mesmo.

veja se a idéia é muito maluca:

public interface Dao<T>...
//define as operações comuns

public class BaseDao<T> implements Dao<T>  
//implementa as operações comuns

caso não tivessem operações especiais, faria assim:

public class CargoController{

CargoController(Dao<Cargo> cargoDao, ...){
...

Caso precisasse de alguma operações especial, ai implementaria em uma classe separada

public interface ClienteDao extends Dao<Clietne>...
//define as operações específicas
List<Cliente> listaPorTipo(Tipo tipo);

public class ClienteDaoImpl implements ClienteDao{

public ClienteDaoImp(Dao<Cliente> dao){...}
//implementa as operações específicas e delega para o basedao as operações básicas

e poderia injetar no controller

public class ClienteController {

ClienteController(ClienteDao clienteDao, ...){
...

o ideal é que desse pra fazer dessa maneira tbm, para os casos onde estas operações não fossem necessárias:

public class ClienteController {

ClienteController(Dao<Cliente> clienteDao, ...){
...

Mas ai acho que já estariamos esbarrando em limitações do java mesmo

To viajando muito? :stuck_out_tongue:

Thiago_Senna

mario.fts:
To com preguiça de dar quote… :lol:

Thiago Senna:

Eu tbm gosto dessa idéia , mas apenas para sistemas muito simples. Eu tive uma situação onde um processo em específico precisava ser feito em jdbc direto, por conta da performance, e tive q reescrever um monte de classes por não ter a persistencia encapsulada dentro de um Dao. A idéia do dao genérico deveria ser essa mesma, funcionar como um entitymanager.

[EDIT] se bem que vendo sua implementação, ela seria mais um dao genérico que usar o entitymanager direto to certo? [/EDIT]

Bom, nao se trata de um DAO. O PersistenceManager é uma classe que encapsulou o Session do hibernate, por exemplo, mas nada impediria de vc utilizar direto o hibernate. Seria algo mais parecido com o padrão UnitOfWork mesmo. As classes Queries são POJO`s simples. Nada demais.

Se for realmente rolar JDBC ai a idéia que sugeri não é um bom negócio. Daí a estratégia de DAO é a ideal mesmo. Mas se tiver certeza q começa com Hibernate e nunca vai mudar para JDBC, ai a opinião que sugeri pode ser legal, IMHO.

mario.fts

Thiago Senna:
mario.fts:
To com preguiça de dar quote… :lol:

Thiago Senna:

Eu tbm gosto dessa idéia , mas apenas para sistemas muito simples. Eu tive uma situação onde um processo em específico precisava ser feito em jdbc direto, por conta da performance, e tive q reescrever um monte de classes por não ter a persistencia encapsulada dentro de um Dao. A idéia do dao genérico deveria ser essa mesma, funcionar como um entitymanager.

[EDIT] se bem que vendo sua implementação, ela seria mais um dao genérico que usar o entitymanager direto to certo? [/EDIT]

Bom, nao se trata de um DAO. O PersistenceManager é uma classe que encapsulou o Session do hibernate, por exemplo, mas nada impediria de vc utilizar direto o hibernate. Seria algo mais parecido com o padrão UnitOfWork mesmo. As classes Queries são POJO`s simples. Nada demais.

Se for realmente rolar JDBC ai a idéia que sugeri não é um bom negócio. Daí a estratégia de DAO é a ideal mesmo. Mas se tiver certeza q começa com Hibernate e nunca vai mudar para JDBC, ai a opinião que sugeri pode ser legal, IMHO.

Sim, exatamenteo o que eu pensei (no segundo momento). Na primeira leitura achei que vc tava falando de usar o Entitymanager diretamente nas classes, no lugar onde vc usaria o dao. Foi esse o erro que eu cometi. Mas desse jeito que vc propos até daria pra usar jdbc, bastaria apenas que seu PersistenceMng fosse uma interface, e no caso de necessiada vc muda a implementação usada conforme sua necessiadade.

aeciovc

@crashy

estou obtendo:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

quando tento executar um DAO similar ao seu.

this.oClass = (Class&lt;ENTITY&gt;) ( (ParameterizedType) getClass().getGenericSuperclass()). getActualTypeArguments()[0];

Criado 19 de agosto de 2010
Ultima resposta 6 de set. de 2010
Respostas 26
Participantes 11