Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Remoção de registros via JPA

Sempre que for necessário remover um registro do banco temos que fazer uma busca por ele? Não é possível remover um registro passando apenas o número do ID?

No caso de uma exclusão em massa isso seria muito oneroso, pois teríamos que buscar todos os registros que queremos excluir do banco para depois remover.

3 respostas

Oi Felipe, tudo bom?

Na verdade, a unica coisa realmente necessária é o ID:

Conta conta = new Conta();
conta.setId(3);

EntityManager em = new JPAUtil().getEntityManager();
em.getTransaction().begin();

em.remove(conta);

em.getTransaction().commit();
em.close();

O EntityManager procura pelo id do objeto e o nome da entidade para poder remover no banco a instancia certa da tabela certa.

Não precisamos da entidade toda populada para isso, só o id ja é suficiente mesmo.

Em uma aplicação MVC a unica coisa que precisaria ser informada a rota/action para remover seria o id de quem vamos remover.

Abraço e bons estudos =)

Oi André, tudo bem sim, obrigado pela resposta.

Seria bom se funcionasse dessa forma (pelo menos no meu caso não funcionou), mas o problema é que nesse caso seria gerada uma exceção, pois a JPA iria identificar que o objeto é "Detached" e não "Managed" e não o excluiria.

Daí que veio a minha preocupação, já que ao invés de gerar uma operação no banco, foram geradas 2 operações, e, em uma exclusão em massa isso seria ruim.

Então vem a dúvida, não existe um método que fale para a JPA algo do tipo "JPA, eu sei que esse id existe, não precisa ir no banco verificar, só exclui o registro no banco pra mim".

solução!

Entendo.

Dando uma olhada na documentação de remoção realmente parece ser inflexivel nesse ponto:

In order to delete an object from the database it has to first be retrieved (no matter which way) and then in an active transaction, it can be deleted using the remove method.

An IllegalArgumentException is thrown by remove if the argument is not a an instance of an entity class or if it is a detached entity.

Ou seja, precisamos resgatar a entidade de qualquer forma para que o remove seja executado sem lançar uma exception.

De qualquer forma, você pode executar essa query manualmente . Entretanto, para casos mais complexos nos quais sua entidade tenha relacionamentos com outras entidades (1x1, 1xN ou NxN), essa abordagem pode se tornar bem maçante.

Quanto a sua preocupação: á que ao invés de gerar uma operação no banco, foram geradas 2 operações, e, em uma exclusão em massa isso seria ruim.

No caso de uma exclusão em massa, acredito que a melhor abordagem seja criar uma query para isso, apontando qual caso especifico você quer excluir.

Mas, mesmo que criar uma query na mão não seja uma opção, se você está excluindo uma entidade é porque ja visualizou ela antes e existe o sistema de cache para segurar esse tipo de requisição duplicada. O problema não seria tão grave mesmo varrendo uma lista para remover todas as entidades contidas.

Criar a query na mão seria dizer para o entitymanager que você sabe que aquele id existe no banco e que não há nenhum relacionamento com outras entidades naquele processo de remoção. Fazer o find é, muito provavelmente, pegar uma entidade que já está cacheada e mandar remover.