Oi, Guilherme! Perdão pela demora em responder.
A diferença está no retorno do merge. O merge(categoria) não transforma a mesma instância que você já tinha em gerenciada. Ele devolve outra instância, agora no estado managed.
No caso do remove, isso é obrigatório porque o método remove() só aceita uma entidade gerenciada. Então, se você fizer assim:
em.remove(categoria);
E essa categoria estiver detached, a remoção falha. Por isso é necessário reatribuir:
categoria = em.merge(categoria);
em.remove(categoria);
Neste ponto, o remove() será executado sobre a instância que o JPA está gerenciando. Já no update, depende de como o código continua depois do merge. Se o método faz só isto:
em.merge(categoria);
não é necessário reatribuir, porque o próprio merge já copia os dados da entidade destacada para a instância gerenciada, e o JPA sincroniza isso no banco no commit ou no flush.
Mas, na aula em que houve clear(), foi preciso reatribuir porque, depois do clear, a instância antiga deixou de ser gerenciada. Então, para continuar trabalhando com a entidade dentro do contexto de persistência, era necessário usar a referência retornada pelo merge:
categoria = em.merge(categoria);
O ponto importante é este:
- Sem reatribuir no update: funciona quando você só quer mandar o JPA mesclar os dados e encerrar ali.
- Com reatribuição no update: necessário quando você ainda vai usar a entidade depois do
merge, porque a instância retornada é a que está managed. - No remove, a reatribuição é necessária porque o
remove() precisa receber justamente essa instância managed.
Veja este exemplo:
Categoria categoriaDetached = new Categoria();
categoriaDetached.setId(1L);
categoriaDetached.setNome("Casa");
Categoria categoriaManaged = em.merge(categoriaDetached);
Depois disso:
categoriaDetached continua detachedcategoriaManaged fica managed
Então, para atualizar, pode bastar:
em.merge(categoriaDetached);
Mas, para remover, precisa ser:
Categoria categoriaManaged = em.merge(categoriaDetached);
em.remove(categoriaManaged);
Ou seja, a diferença não está no funcionamento do merge, e sim no que cada operação exige depois dele. O update pode acontecer só com a mesclagem dos dados. Já o remove exige a instância gerenciada retornada pelo merge.
Fico à disposição!