我有下一个spring rest控制器来处理我的异常:
@ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public @ResponseBody ExceptionResponseDTO hiberAnnotationExceptionHandler(ConstraintViolationException exception) { return new ExceptionResponseDTO("Entity is null or we are out of range!", exception.getMessage(), ExceptionMapper.INSTANCE.exceptionToExceptionDTO(exception)); }
我的 实体 类:
@Entity public class Device { @Id @Column(name="name", nullable = false) private String Name; @Column(name = "send_date") @NotNull private Date sendDate; }
我尝试模拟 ConstraintViolationException ,因此在我的控制器中使用下一个代码:
Device d = new Device(); d.setName("sdsdsd"); d.setSendDate(null); deviceRepository.save(d);
结果,我收到下一个异常:
[dispatcherServlet] :?-路径为[]的上下文中的Servlet [dispatcherServlet]的Servlet.service()抛出异常[请求处理失败;嵌套的异常是org.springframework.transaction.TransactionSystemException:无法提交JPA事务。嵌套的异常是javax.persistence.RollbackException:根本原因提交事务时出错,原因是javax.validation.ConstraintViolationException:组[javax.validation.groups.Default,]的更新期间,对类[com.entity.Device]的验证失败违反约束的列表:[ConstraintViolationImpl {interpolatedMessage =’可能不为空’,propertyPath = sendDate,rootBeanClass = class com.entity.Device,messageTemplate =’{javax.validation.constraints.NotNull.message}’}]
因此,从 堆栈跟踪中 可以看到,我首先收到 TransactionSystemException ,因此,我的 ExceptionHandler 方法( hiberAnnotationExceptionHandler )不被调用。所以我的问题是如何模拟此异常( ConstraintViolationException )?提前致谢。
TransactionSystemException的原因
如果您进入代码AbstractEntityManagerImpl.convert()方法,您将看到默认情况下它不处理任何特定的异常(如ConstraintViolation),而是仅抛出并包装PersistenceException。
正确解决异常的解决方案
> <bean id="transactionManager" > class="org.springframework.orm.jpa.JpaTransactionManager"> > <property name="entityManagerFactory" ref="entityManagerFactory"/> > <property name="jpaDialect" ref="jpaDialect"/> > </bean> > > <bean id="jpaDialect" > class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
HibernateJpaDialect捕获这些异常并将其转换为Spring特定的异常,如下所示
> if (ex instanceof ConstraintViolationException) { > ConstraintViolationException jdbcEx = > (ConstraintViolationException) ex; > return new DataIntegrityViolationException(ex.getMessage() + > "; SQL [" + jdbcEx.getSQL() + > "]; constraint [" + jdbcEx.getConstraintName() + "]", > ex); > }
> <bean id="entityManagerFactory" > class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> > <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" > class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
@ExceptionHandler(DataIntegrityViolationException.class)