Tratamento de erros no DAO - Lançar exceções ou tratar no próprio DAO?

Eu estou com um problema na minha aplicação que ainda não consegui resolver. É um problema de validação. Sempre que um form é preenchido e enviado, a aplicação no servidor faz a validação, usando o Validator do VRaptor (mas isso é um detalhe indiferente para a questão) e, se os dados forem pré-validados, chama-se o DAO.

Teoricamente o DAO não retornaria nenhum tipo de erro se o banco estiver rodando e as consultas já forem testadas: em ambiente de produção espera-se que as ferramentas funcionem estáveis. Tudo bem. Mas alguns problemas podem surgir com a adição de constraints nas lógicas do BD. No meu caso eu tenho uma coluna com o atributo UNIQUE, e não sei como fazer essa validação na minha aplicação.

Estou com 2 soluções, gostaria de pegar a experiência dos colegas e gerar uma discussão sobre essas soluções:

  1. O DAO trata as exceções dentro dos seus métodos, fazendo o rollback das transações que não puderam ser concluídas, e lançando novas exceções que serão tratadas pela lógica da aplicação (camada de BL, a camada que usa o DAO).
  2. Usar um DAO mais limpo, de forma que ele trate as exceções internas (fazendo o rollback quando necessário), mas que não gere exceções. Nesse caso entende-se que o programa vá rodar 99,999% das vezes sem problemas, e que se o DAO gerar exceção é porque o banco está fora do ar e a aplicação, por tabela, também está fora do ar. Nesse caso, checa-se as constraints de banco na camada de BL também, utilizando queries (SELET WHERE nome = input, no caso de verificação de unicidade dos registros).

O que vocês fariam? A solução 1 obviamente é a mais elegante, mas o código fica lotado de try/catch e perde legibilidade. No meu caso eu estou fazendo a pré-validação dos dados no BL, faço a chamada ao DAO e verifico por erros novamente. É comum usar DAOs que lançam exceções?

Use a solução 2, e gere RuntimeExceptions para os casos extremos.
Afinal, eles são mesmo extremos.

As runtime acabam sendo logadas em algum momento da sua aplicação.

Opa, escrevi sobre isso no meu blog ontem… http://www.sectioaurea.com.br/diogopontual !!!

Vc falou que o seu DAO trata das transações, normalmente acho que isso deve ficar um pouco mais acima.

Abraço

Diogo, esse é outro ponto a se levar em conta. Como minha aplicação é simples, o DAO gerenciar as transações é suficiente. O ideal mesmo era fazer o DAO intermediar a gerência de transações, mas a lógica efetivamente abrir e fechá-las.

Outra coisa, porque não existe um GenericDAO definitivo no Java? É algo tão complexo que poucas pessoas usariam? O que eu vejo são vários genericdaos espalhados em blogs pessoais, mas em geral não são utilizáveis na vida real (muito simples, sem tratamento de erros, pouco elegantes).