Marcelo Magalhaes:
Caros amigos,
Estou com uma dúvida se o código abaixo funciona. Posso garantir que o objeto entity SEMPRE terá um método getId().
public void save(T entity)
{
try
{
Method method = type.getMethod("getId", Object.class);
if (method.invoke(entity) == null)
{
em.persist(entity);
}
else
{
em.merge(entity);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
O que estou tentando fazer é juntar o persist com o merge em um só método no DAO, usando o Id como verificador se o objeto é novo (persist) ou uma alteração (merge).
Respondendo estritamente à sua pergunta, vc cria uma interface (Entity, por exemplo) com getId() e faz assim
public DAO<T extends Entity> {
public void save(T entity) {
if (entity.getId() == null ){
// la la la la
}
}
}
(pode usar uma classe em vez de interface também)
Isto é a forma de usar generics para dizer que métodos existem em T. Reflection pode funcionar, mas pode não funcionar ( se o cara passar save(new Object()) vai dar erro).
Com extends o compilador garante para vc que apenas classes que herdam de entity podem ser usadas em save(), o que é muito melhor.
Agora, uma nota: testar se o id é ou não nulo não é uma regra de negocio ( o id não é um atributo de negocio) , é válido e comum fazer este teste. Aliás é o que o hibernate faz no saveOrUpdate.
Vc deveria usar um DomainStore diretamente ( o entitymanager) e não este tipo de codigo que vc está tentando fazer. Se passar para o entitymanager ele irá saber o que fazer sem precisar do getId porque ele têm o modelo do objeto e sabe se ele é do domínio ou não. Isto simplifica muito o codigo das suas entidades que não tem que herdar de ninguem.