Spring的持久性异常翻译不适用于Hibernate 5

时间:2017-08-30 09:23:35

标签: spring hibernate jpa

我使用的是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异常,因此不会发生翻译。

我仍然承认问题是我的,因为我找不到任何人如此流行的用法面临这个问题。有任何想法吗?谢谢!

1 个答案:

答案 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;
}

现在它按预期工作。