Como me recupero de uma exceção desmarcada?

Exceções não verificadas são boas se você deseja lidar com todas as falhas da mesma maneira, por exemplo, registrando-a e pulando para a próxima solicitação, exibindo uma mensagem para o usuário e manipulando o próximo evento, etc. Se esse for o meu caso de uso, tudo o que o que fazer é capturar algum tipo de exceção geral em um nível alto no meu sistema e lidar com tudo da mesma maneira.

Mas quero me recuperar de problemas específicos e não tenho certeza da melhor maneira de abordá-lo com exceções não verificadas. Aqui está um exemplo concreto.

Suponha que eu tenha um aplicativo da Web, criado usando o Struts2 e o Hibernate. Se uma exceção aparecer na minha "ação", eu a registro e mostro um pedido de desculpas bastante ao usuário. Mas uma das funções do meu aplicativo da web é criar novas contas de usuário, que exigem um nome de usuário exclusivo. Se um usuário escolhe um nome que já existe, o Hibernate lança umorg.hibernate.exception.ConstraintViolationException (uma exceção não verificada) nas entranhas do meu sistema. Eu realmente gostaria de me recuperar desse problema em particular, pedindo ao usuário que escolha outro nome de usuário, em vez de fornecer a mesma mensagem "registramos o seu problema, mas por enquanto você está hospedado".

Aqui estão alguns pontos a serem considerados:

Muitas pessoas criam contas simultaneamente. Não quero bloquear toda a tabela de usuários entre um "SELECT" para ver se o nome existe e um "INSERT", se não existir. No caso de bancos de dados relacionais, pode haver alguns truques para contornar isso, mas o que realmente me interessa é o caso geral em que a verificação prévia de uma exceção não funcionará devido a uma condição fundamental de corrida. O mesmo se aplica à procura de um arquivo no sistema de arquivos etc.Dada a propensão do meu CTO para o gerenciamento drive-by induzido pela leitura de colunas de tecnologia em "Inc.", preciso de uma camada de indireção em torno do mecanismo de persistência para que eu possa expulsar o Hibernate e usar o Kodo ou qualquer outra coisa, sem alterar nada, exceto o mais baixo camada de código de persistência. De fato, existem várias camadas de abstração no meu sistema. Como posso impedir que eles vazem, apesar de exceções não verificadas?Uma das fraquezas declaradas das exceções verificadas é ter que "manipular" elas em todas as chamadas na pilha - declarando que um método de chamada as lança ou capturando-as e tratando-as. Manipulá-los geralmente significa agrupá-los em outra exceção verificada de um tipo apropriado ao nível de abstração. Assim, por exemplo, em terras com exceção marcada, uma implementação do meu UserRegistry baseada em sistema de arquivos pode pegarIOException, enquanto uma implementação de banco de dados pegariaSQLException, mas ambos lançariam umUserNotFoundException que oculta a implementação subjacente. Como aproveito as exceções não verificadas, poupando-me do ônus desse empacotamento em cada camada, sem vazar detalhes da implementação?

questionAnswers(9)

yourAnswerToTheQuestion