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.
carlos.e.a
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.
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.
Um exemplo básico, apenas com create() e find()
publicclassGenericDaoTest{publicstaticvoidmain(String[]args){// Cria o DAO, parametrizado apenas pelo tipo da ENTIDADE, sem usar o tipo do IDGenericDao<Entidade>dao=newGenericDao<Entidade>(Entidade.class);// Sem novidades no create, ele não usa o ID de qualquer maneiraEntidadee1=newEntidade();dao.create(e1);IntegeridToSearch=10;// Chamando método genérico, passando o parâmetro do tipo do IDEntidadee2=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.Entidadee3=dao.find(idToSearch);}}classEntidade{Integerid;StringoutroCampo;}classGenericDao<T>{Class<T>entityClass;EntityManagerem;// Poderia tambem ser a sessao do hibernatepublicGenericDao(Class<T>entityClass){this.entityClass=entityClass;}// Metodo que nao precisa do ID. Ok, funciona normalmentevoidcreate(Tentity){em.persist(entity);}// Metodo que precisa do ID é genérico, // parametrizado pelo tipo do ID<ID_TYPE>Tfind(ID_TYPEid){returnem.find(entityClass,id);}}
wagnerfrancisco
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.
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…
gomesrod
É verdade! Pensei na praticidade mas acaba perdendo em segurança.