spring rest中的ConstraintViolationException异常

spring rest中的ConstraintViolationException异常,spring,hibernate,Spring,Hibernate,我有下一个spring rest控制器来处理我的异常: @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public @ResponseBody ExceptionResponseDTO hiberAnnotationExceptionHandler(ConstraintViolationException exception) { return

我有下一个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);
因此,我收到下一个异常:

@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));
}
[dispatcherServlet]:?-Servlet的Servlet.service() 路径为[]的上下文中的[dispatcherServlet]引发了异常[Request] 处理失败;嵌套异常为 org.springframework.transaction.TransactionSystemException:无法 提交JPA事务;嵌套异常为 javax.persistence.RollbackException:提交 有根本原因的交易] javax.validation.ConstraintViolationException:的验证失败 类[com.entity.Device] 在组[javax.validation.groups.Default,]列表的更新期间 违反约束的情况:[ ConstraintViolationImpl{interpolatedMessage='不能为null', propertyPath=sendDate,rootBeanClass=class com.entity.Device, messageTemplate='{javax.validation.constraints.NotNull.message}}]

因此,正如您从stacktrace中看到的,我首先接收到TransactionSystemException,因此我的ExceptionHandler方法(HiberNotationExceptionHandler)没有调用。所以我的问题是如何模拟这个异常(ConstraintViolationException)?
提前感谢。

交易系统异常的原因

  • Hibernate实体管理器负责引发所有Hibernate异常
  • 如果进入代码方法内部, 您将看到,默认情况下,它不会处理任何特定的异常,比如ConstraintViolation,而只是在PersistenceException中抛出和包装

  • JPA事务管理器捕获上述异常如果您在@transaction内调用代码并转换为TransactionSystemException,您可以看到spring JPA事务管理器的代码class=“org.springframework.orm.JPA.JpaTransactionManager”
  • 正确解决异常的解决方案

  • 首先注册一个JPA方言,它可以拦截那些HibernateeException,并在事务管理器bean中封装成特定的spring异常
  • 您还可以注册entitymanager正在使用hibernate jpaVendorAdapter,以确保您在任何地方都使用hibernate
  • 
    
  • 现在在控制器中,您可以预期dataIntegrityException,它来自hibernate方言,由于ConstraintViolationException而引发
  • @ExceptionHandler(DataIntegrityViolationException.class)


    尝试重现以下步骤:

    • 添加到您的网络配置文件
    • @Validated

    • 在控制器的方法中用

    @Pattern(regexp=“\\d+”)@RequestParam String param

    • 然后只需使用参数调用该方法,如“一些没有数字的字符串”

    如果要使用该实体。做一些类似于

    @Valid @RequestBody Device device 
    
    用你的方法您可以跳过前面的所有步骤。

    <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"/>
    
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
    
    @Valid @RequestBody Device device