Bom dia, pessoal!
Estou com uma dúvida conceitual sobre quais práticas são recomendadas no que diz respeito ao tratamento de exceções com JPA utilizando EJB e transações gerenciadas pelo container.
No caso em estudo, estou tentando “pegar” uma exceção de chave duplicada, algo bem bobo, como um email ou um nome de usuário que já existe na base de dados. Acontece que não consigo “pegar” a exceção de chave duplicada, pois como minhas transações são gerenciadas pelo container, ela só é lançada quando do commit (mas como é CMT, difícil saber quando isso vai acontecer, né?)
E outra, ainda que eu forçasse a situação (colocando um flush logo após o persist), o JPA me lança uma PersistenceException. Neste caso, seria melhor que lançasse EntityExistsException, pois do jeito que está teria que ficar percorredo o stackTrace para verifcar que exceção de fato aconteceu. Também não me parece ser de bom tom sair percorrendo o stackTrace e ficar analisando as exceções do hibernate/eclipselink ou do postgresql/mysql/etc, só para saber se houve uma exceção de duplicidade de chave, pois isso acaba por deixar meu código dependente do ORM e do DB.
Ainda assim, ficar colocando flush pelo caminho não me parece uma solução boa.
A solução que encontrei (que ao meu ver também não parece ser muito “bonita”, mas é a menos intrusiva) foi fazer uma busca na base antes de salvar o registro, e ao encontrar registro com mesma chave, lançar uma exceção minha, anotada com @ApplicationException(rollback=true). Mas teria alguma maneira mais elegante ou que utilize o JPA para capturar uma exceção de duplicidade de chave sem ter que ficar fazendo buscas na base de dados antes de efetuar o registro???
Tenho buscado bastante isso em fóruns e aqui mesmo no GUJ, mas ainda não encontrei uma maneira diferente de resolver isso.
Afinal, sobre as boas práticas no tratamento de exceções, a forma como estou fazendo está legal? Pois não vejo outra solução para casos como estes.