Problema muito estranho ocorrendo. Estou usando JPA como API de persistência e Java 5.
Tenho uma classe com um método de busca definido assim:
public <T extends BaseEntity> T find(Class<T> clazz, Serializable pk) {
try {
return em.find(clazz, pk);
} catch (RuntimeException e) {
throw new BaseException(e);
}
}
Porém o código acima não compila (ao menos no JDeveloper 10.1.3.2-4066). Ocorre a seguinte mensagem de erro:
Ele diz que não encontra o método find no EntityManager, porém, segundo a documentação da API ele é definido assim:
No entanto, se eu mudo de <T extends …> de BaseEntity para Object na assinatura do método, ele compila:
public <T extends Object> T find(Class<T> clazz, Serializable pk) {
try {
return em.find(clazz, pk);
} catch (RuntimeException e) {
throw new BaseException(e);
}
}
Não entendo porque funciona com Object e não funciona com a minha interface BaseEntity.
Porém, eu acabei mudando o código como abaixo e funciona:
public <T extends BaseEntity> T find(Class clazz, Serializable pk) {
try {
return (T) em.find(clazz, pk);
} catch (RuntimeException e) {
throw new BaseException(e);
}
}
Retirei o <T> do primeiro argumento e faço um cast do retorno do método em.find().
Alguém tem idéia do porquê???
ddduran
Novembro 1, 2007, 10:02am
#2
Você já achou tudo.
o grande problema é que seu IDE lhe traiu com a mensagem de erro.
por exemplo fiz o mesmo código que você aqui e o erro que me traz é “can not convert T to T”
você tem que lembrar que quando rodar seus generics serão trocados por "Classes reais"
então vamos fazer o que você fez sem generics, ficaria assim
public BaseEntity find(Class clazz, Serializable pk) {
try {
return em.find(clazz, pk); // esse metodo retorna um Object logo precisa de um cast, afinal o mais generico aceita o mais
// especifico, o contrario não
} catch (RuntimeException e) {
throw new BaseException(e);
}
}
então tudo que precisava era do Cast.
acho que o unico problema foi seu IDE que lhe pregou uma peça
Mesmo se eu fizer assim, não rola:
public <T extends BaseEntity> T find(Class clazz, Serializable pk) {
try {
return (T) em.find(clazz, pk);
} catch (RuntimeException e) {
throw new BaseException(e);
}
}
Acontece, que eu defino que T é subclasse de BaseEntity, logo, ele pode receber qualquer filho dela e retorná-lo.
Eu estou enganado?
ddduran
Novembro 1, 2007, 10:12am
#4
então aqui funcionou normalmente, só colocando o cast.
você está certo, deve aceitar qualquer filho de BaseEntity
você pode mandar a declaração da sua classe?
faz um teste, tenta compilar esse projeto com o bom e velho javac do console
só para averiguar se é o IDE
javac? Muitas dependências de biblotecas… Deixa pra lá.
Talvez eu tente no Eclipse depois.
ddduran
Novembro 1, 2007, 10:17am
#6
[quote=danieldestro]javac? Muitas dependências de biblotecas… Deixa pra lá.
Talvez eu tente no Eclipse depois.[/quote]
hahaha meio chato mesmo eu nem lebro como usa direito (pobre escravo de IDE que sou)
mas eu fiz no eclipse mesmo
ddduran
Novembro 1, 2007, 10:39am
#7
mesmo assim manda a declaração da sua classe
e se testar no eclipse e funcar, avisa ae para eu nunca usar o JDeveloper