我使用的是Spring 4.3.10和Hibernate 5.2.10(我已经从Hibernate 4迁移到了下面的问题)。声明了以下后处理器,以便利用Spring在@Repository
标记的服务中翻译Hibernate异常。
@Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
我的代码违反了数据库约束,因此Hibernate将抛出一个org.hibernate.exception.ConstraintViolationException
,我希望将其转换为Spring的通用org.springframework.dao.DataIntegrityViolationException
。但是,在Hibernate 4中工作的不在5中。
正如我从源代码中看到的那样,Hibernate 5在内部使用ExceptionConverter
,它将ConstraintViolationException
与JPA javax.persistence.PersistenceException
打包在一起。以下是Spring的LocalSessionFactoryBean
translateExceptionIfPossible()
(继承自HibernateExceptionTranslator
)的样子:
@Override
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
if (ex instanceof HibernateException) {
return convertHibernateAccessException((HibernateException) ex);
}
return null;
}
这里有一个PersistenceException
实例,而不是一个简单的Hibernate异常,因此不会发生翻译。
我仍然承认问题是我的,因为我找不到任何人如此流行的用法面临这个问题。有任何想法吗?谢谢!
答案 0 :(得分:1)
这是一个配置问题。问题出在spring-orm
库中,其版本为4.3.1,而其余的Spring组件为4.3.10。在较新版本中,HibernateExceptionTranslator.translateExceptionIfPossible()
看起来已升级:
@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;
}
现在它按预期工作。