Olá pessoal,
Bom, estou usando uma API(acho que pela descrição do problema alguns saberão qual é) que por algum motivo que desconheço quando vou criar um Dao o generico é da seguinte forma:
Dao<T,ID>
Onde T seria o tipo da entidade e ID o tipo do id da classe. Só que esse ID ao meu ver é totalmente desnecessário ja que posso descobrir por reflection. Então criei um metodo que fazia essa descoberta. Só que me deparei com o problema:
Como passo o tipo descoberto para o Dao<T,ID>. Meu metodo retorna um Class<?> e se chama getIdType(T classe) onde classe é a entidade. Quando tento fazer Dao<T, getIdType(classe)> não funciona. O que afinal devo passar quando estou instanciando um tipo generico? Isso abalou meus conhecimentos de generics :roll:
Fiz umas buscas mas nao encontrei nada, principalmente pela dificuldade de formular uma busca para tal.
Isso não funciona porque os Generics são aplicados em tempo de compilação do programa e não de execução. Essa maneira de fazer exigiria a execução do método getIdType() para obter o tipo, o que não faz nenhum sentido para o compilador.
Certo,
Alguma sugestao de como resolver isso? xD
Pq fica mt tosco passar como parametro pro meu metodo uma coisa que eu posso descobrir e livrar quem está chamando disso.
Você pode parametrizar a classe apenas pelo tipo da entidade (T) , e os métodos que precisam do ID seriam especialmente parametrizados com o tipo do ID.
Na maioria das situações essa solução vai se comportar exatamente como você quer, porque ele é capaz de deduzir o tipo do ID de acordo com o que foi passado no parâmetro.
Um exemplo básico, apenas com create() e find()
[code]public class GenericDaoTest {
public static void main(String[] args) {
// Cria o DAO, parametrizado apenas pelo tipo da ENTIDADE, sem usar o tipo do ID
GenericDao<Entidade> dao = new GenericDao<Entidade>(Entidade.class);
// Sem novidades no create, ele não usa o ID de qualquer maneira
Entidade e1 = new Entidade();
dao.create(e1);
Integer idToSearch = 10;
// Chamando método genérico, passando o parâmetro do tipo do ID
Entidade e2 = dao.<Integer>find(idToSearch);
// Na verdade não precisa do tipo, ele é capaz de deduzir pelo
// que foi passado no parâmetro!
// No final o tipo do ID fica transparente.
Entidade e3 = dao.find(idToSearch);
}
}
class Entidade {
Integer id;
String outroCampo;
}
class GenericDao {
Class entityClass;
EntityManager em; // Poderia tambem ser a sessao do hibernate
public GenericDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
// Metodo que nao precisa do ID. Ok, funciona normalmente
void create(T entity) {
em.persist(entity);
}
// Metodo que precisa do ID é genérico,
// parametrizado pelo tipo do ID
<ID_TYPE> T find(ID_TYPE id) {
return em.find(entityClass, id);
}
}[/code]
[quote=gomesrod]Você pode parametrizar a classe apenas pelo tipo da entidade (T) , e os métodos que precisam do ID seriam especialmente parametrizados com o tipo do ID.
Na maioria das situações essa solução vai se comportar exatamente como você quer, porque ele é capaz de deduzir o tipo do ID de acordo com o que foi passado no parâmetro.[/quote]
Mas nesse caso qualquer tipo que eu passe por parâmetro vai ser considerado como o tipo do id, certo? A checagem do tipo do id meio que se perde. Se você passar o tipo errado, só vai descobrir em tempo de execução.
Eu ainda prefiro passar o T e o ID pro Dao, se as minhas entidades tiverem ids de tipos diferentes…
É verdade! Pensei na praticidade mas acaba perdendo em segurança.