O meu intuito era criar um modo genérico e transparente de tratar exceções unckecked e mostrar mensagens "amigáveis" na tela (Para um conceito quase exatamente definitivo sobre o verbete "amigável", favor consultar o Guia do Mochileiro das Galáxias). O Spring diz que consegue converter todo e qualquer tipo de exceção de banco de dados (checada ou não) em uma hierarquia própria de exceções (não checadas) para a comodidade do desenvolvedor. Assim, não nos preocuparíamos em lançar exceções checadas nas nossas classes @Repository.
Entretanto, eu não estava conseguindo, até atentar para um pequeno detalhe na minha configuração do Spring:
Adicionando isso à minha configuração do Spring, fiz o teste: provoquei uma exceção de chave duplicada na minha tela e a exceção que eu obtive foi uma DataIntegrityViolationException. Talvez seja possível obter o mesmo resultado se você já usa algo como JpaDaoSupport, mas para quem deseja implementar repositórios planos com JPA, essa é uma boa alternativa.
A idéia agora é utilizar o Spring AOP e o AspectJ para implementar um tratamento de exceções para toda a hierarquia. Será que eu consigo? A idéia inicial é usar essa hierarquia de exceções do spring como ponto de partida. Daí em diante, chegar nas SQLExceptions (para ocasiões específicas) e traduzir os códigos de erro em mensagens, na medida do possível.
Common data access exceptions. Spring pode envolver exceções de sua ferramenta ORM, convertendo-as de exceções proprietárias (potencialmente checadas) para uma hierarquia comum de exceções não checadas DataAccessException. Este recurso permite que você manipule a maioria das exceções persistentes (que são não-recuperáveis) apenas nas camadas mais adequadas, sem o uso dos irritantes blocos try-catch. Você ainda pode interceptar e manipular exceções conforme necessário. Lembre-se que as exceções JDBC (incluindo dialetos específicos de banco de dados) também são convertidos para a mesma hierarquia, o que significa que você pode realizar algumas operações com JDBC dentro de um modelo de programação consistente. [Fonte: Sring 3.0.x Documentation - Object Relational Mapping (ORM) Data Access]
Entretanto, eu não estava conseguindo, até atentar para um pequeno detalhe na minha configuração do Spring:
<!-- Gerenciador da criacao e manutencao dos EntityManager --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitManager" ref="persistenceUnitManager" /> <property name="persistenceUnitName" value="myPersistenceUnit"/> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="${hibernate.show_sql}" p:databasePlatform="${hibernate.dialect}" > </bean> </property> </bean>
Adicionando isso à minha configuração do Spring, fiz o teste: provoquei uma exceção de chave duplicada na minha tela e a exceção que eu obtive foi uma DataIntegrityViolationException. Talvez seja possível obter o mesmo resultado se você já usa algo como JpaDaoSupport, mas para quem deseja implementar repositórios planos com JPA, essa é uma boa alternativa.
A idéia agora é utilizar o Spring AOP e o AspectJ para implementar um tratamento de exceções para toda a hierarquia. Será que eu consigo? A idéia inicial é usar essa hierarquia de exceções do spring como ponto de partida. Daí em diante, chegar nas SQLExceptions (para ocasiões específicas) e traduzir os códigos de erro em mensagens, na medida do possível.