TransactionSystemException的原因
- hibernate实体管理器负责引发所有hibernate异常
如果您进入代码AbstractEntityManagerImpl.convert()方法,您将看到默认情况下它不处理任何特定的异常(如ConstraintViolation),而是仅抛出并包装PersistenceException。
- 如果您在@Transaction中调用代码并将其转换为TransactionSystemException,则JPA事务管理器会捕获上述异常,您可以看到spring JPA事务管理器的代码class =“ org.springframework.orm.jpa.JpaTransactionManager”
正确解决异常的解决方案
- 首先注册一个JPA方言,它可以拦截那些HibernateExceptions并包装到特定的Spring异常中,例如在事务管理器bean中。
> <bean id="transactionManager"> >> <property name="entityManagerFactory" ref="entityManagerFactory"/>> <property name="jpaDialect" ref="jpaDialect"/>> </bean>> > <bean id="jpaDialect"> />
HibernateJpaDialect捕获这些异常并将其转换为Spring特定的异常,如下所示
> if (ex instanceof ConstraintViolationException) {> ConstraintViolationException jdbcEx => (ConstraintViolationException) ex;> return new DataIntegrityViolationException(ex.getMessage() +> "; SQL [" + jdbcEx.getSQL() +> "]; constraint [" + jdbcEx.getConstraintName() + "]",> ex);>}- 您还可以注册您的entitymanager正在使用hibernatejpaVendorAdapter来确保您在任何地方都使用hibernate。
> <bean id="entityManagerFactory"> >><property name="packagesToScan" value="com.pack.model" />> <property name="persistenceUnitManager"> ref="persistenceUnitManager"/>> <property name="persistenceUnitName" value="entityManager"/>> <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>> </bean> <bean id="jpaVendorAdapter"> />
- 现在在您的控制器中,您可以期待dataIntegrityException,它是由于ConstraintViolationException而抛出的hibernate方言产生的
@ExceptionHandler(DataIntegrityViolationException.class)



