Tenho uma Pessoa com uma lista de emails. Quando quero atualizar os dados da pessoa utilizo o seguinte código:
@Override
@SuppressWarnings("unchecked")
public boolean update(T trasientObject, PK id) {
EntityManager em = null;
boolean ok = false;
try {
em = getEntityManager();
em.getTransaction().begin();
Object o = em.find(trasientObject.getClass(), id);
o = trasientObject.getClass().cast(trasientObject);
em.merge(o);
em.getTransaction().commit();
ok = true;
} catch (Exception ex) {
throw ex;
} finally {
if (em != null)
em.close();
if (ok) {
return true;
} else {
return false;
}
}
}
E está funcionando tanto para os valores de pessoa como também quando adiciono mais um email na lista de emails, apenas dou update e tudo ok.
O problema está quando removo um ou mais emails da lista de emails e quero atualizar a entidade pessoa, ela atualiza os campos mas a lista de emails não! Tipo, ela atualiza o nome da pessoa se eu mudar o nome mas não remove o emails se eu remover o email dessa pessoa.
E agora? O que deve fazer? Já rodei aqui pelo fórum e não consegui nada conciso! Me ajudem! Obrigado.
Sei sim, a linha “o = trasientObject.getClass().cast(trasientObject);” é porque estou usando um DAO Genérico implementado por várias classes, então como na linha que segue dou o merge(), objeto passado ao método tem que ser do tipo que eu quero atualizar, por isso faço o cast “indireto/dinâmico” vamos dizer assim. Sobre a transação dá pra ver pelo código que está dentro do escopo da sessão…
É como eu tô dizendo, quando a atualização envolve adicionar um elemento a lista, funciona; quando é pra remover, não! :roll:
Exato, pelo fato de ser o genério você precisa deixar seu objeto attached, depois alterar a lista e depois salvar.
Na boa? precisa disso tudo para ser genérico não viu. ^^
E como faço isso da melhor maneira? Já tentei dar find antes e setar os objetos mas dá no mesmo…
public boolean editar(Pessoa pessoa) throws EntidadeNaoExistenteException, Exception {
boolean ok = false;
EntityManager em = null;
GenericDAOImplement<Pessoa, Long> genericDAO = new GenericDAOImplement<Pessoa, Long>();
try {
em = genericDAO.getEntityManager();
em.getTransaction().begin();
Pessoa pessoaDoBD = em.find(pessoa.getClass(), pessoa.getId());
System.out.println(pessoaDoBD);
if (pessoaDoBD == null) {
throw new EntidadeNaoExistenteException("A pessoa com id " + pessoa.getId() + " não existe mais.");
}
//Seta novos dados na instância gerenciada pelo EntityManager.
pessoaDoBD.setApelido(pessoa.getApelido());
pessoaDoBD.setCnpj(pessoa.getCnpj());
pessoaDoBD.setCpf(pessoa.getCpf());
pessoaDoBD.setDataDeNascimento(pessoa.getDataDeNascimento());
//Lista de emails aqui... (Estou repassando uma lista com menos elementos então deveria remover)
pessoaDoBD.setEmails(pessoa.getEmails());
pessoaDoBD.setEndereco(pessoa.getEndereco());
pessoaDoBD.setId(pessoa.getId());
pessoaDoBD.setLogin(pessoa.getLogin());
pessoaDoBD.setNome(pessoa.getNome());
pessoaDoBD.setPathFoto(pessoa.getPathFoto());
pessoaDoBD.setRg(pessoa.getRg());
pessoaDoBD.setRegras(pessoa.getRegras());
pessoaDoBD.setSalDaSenha(pessoa.getSalDaSenha());
pessoaDoBD.setSenha(pessoa.getSenha());
pessoaDoBD.setSexo(pessoa.getSexo());
pessoaDoBD.setTelefones(pessoa.getTelefones());
pessoaDoBD.setUsuarioDoSistema(pessoa.isUsuarioDoSistema());
if (genericDAO.update(pessoa))
ok = true;
em.merge(pessoa);
em.getTransaction().commit();
} catch (Exception ex) {
String msg = ex.getLocalizedMessage();
throw ex;
} finally {
if (em != null)
em.close();
if (ok)
return true;
else
return false;
}
}
Não repara no código, é só pra testar, mas mesmo assim nada…
Eu costumo fazer o seguinte.
Vamos supor q eu queria adicionar um email na pessoa:[code]// pessoaId ou então o objeto pessoa, você quem escolhe
public void adicionarEmail(int pessoaId, Email email){
// inicia transação e outras cofingurações
Pessoa pessoa = em.find(Pessoa.class, pessoaId);
//uso apenas caso o cascade não esteja persist
em.persist(email);
pessoa.getEmails().add(email);
em.merge(pessoa);
// commit e tals
}[/code]Repare que em nenhum momento eu passo uma nova coleção de objetos. O email passado também deve estar “attached” à transação.
Para excluir um email, você teria que fazer pessoas.setEmail(null); Mas antes do delete salvava os emails e após o delete apagava um por um.
Ou então fazia um bulk delete.