Reputation: 1224
I am using Spring 4.3.10 and Hibernate 5.2.10 (I've migrated from Hibernate 4 since which moment got into below problem). The following post-processor is declared in order to take advantage of Spring's translation of Hibernate exceptions in my @Repository
-marked service.
@Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
My code violates a DB constraint, so Hibernate will throw a org.hibernate.exception.ConstraintViolationException
which I expect to translate into Spring's generic org.springframework.dao.DataIntegrityViolationException
. However, what was working in Hibernate 4 does not in 5.
As I see from the source code, Hibernate 5 uses internally its ExceptionConverter
which wraps the ConstraintViolationException
with a JPA's javax.persistence.PersistenceException
. Here's how Spring's LocalSessionFactoryBean
's translateExceptionIfPossible()
(inherited from HibernateExceptionTranslator
) looks like:
@Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
if (ex instanceof HibernateException) {
return convertHibernateAccessException((HibernateException) ex);
}
return null;
}
An instance of PersistenceException
instead of a bare Hibernate exception comes here, so translation won't happen.
I still admit the problem is mine as I couldn't find anyone facing this problem with such a popular usage. Any Ideas? Thanks!
Upvotes: 0
Views: 1287
Reputation: 1224
It was a configuration issue. The problem was in spring-orm
library which was of version 4.3.1 while the rest of Spring components were of 4.3.10. In the newer version, HibernateExceptionTranslator.translateExceptionIfPossible()
looks upgraded:
@Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
if (ex instanceof HibernateException) {
return convertHibernateAccessException((HibernateException) ex);
}
if (ex instanceof PersistenceException) {
if (ex.getCause() instanceof HibernateException) {
// this is my case!
return convertHibernateAccessException((HibernateException) ex.getCause());
}
return EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(ex);
}
return null;
}
Now it works as expected.
Upvotes: 1