首页 > 解决方案 > 如何在 Spring Boot 中捕获 hibernate/jpa 约束违规?

问题描述

我一直无法在 ResponseEntityExceptionHandler 中捕获 ConstraintViolationException(或 DataIntegrityViolationException)。我想在响应中返回 jpa 失败(例如违反了哪个约束)。(我不喜欢在方法参数上使用@Valid 并捕获handleMethodArgumentNotValid)。

...
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataIntegrityViolationException;

@ControllerAdvice
public class PstExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler({ConstraintViolationException.class})
    public ResponseEntity<Object> handleConstraintViolation(
        ConstraintViolationException ex, WebRequest request) {

        ...

        return new ResponseEntity<Object>(...);
    }
}

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Entity
public class Student {

    @Id
    private Long id;

    @NotNull
    private String name;

    @NotNull
    @Size(min=7, message="Passport should have at least 7 characters")
    private String passportNumber;

    public Student() {
    }

...

}

@RequestMapping(value = "/addstudent"...)
@ResponseBody
public ResponseEntity<Object> addStudent(@RequestBody StudentDto studentDto) {

    Student student = new Student();
    student.setId(studentDto.getId());                          // 1L
    student.setName(studentDto.getName());                      // "helen"
    student.setPassportNumber(studentDto.getPassportNumber());  // "321"

    studentRepository.save(student);

    return ResponseEntity.accepted().body(student);
}

谢谢你...

标签: hibernatespring-mvcspring-bootspring-data-jpa

解决方案


不考虑 ConstraintViolationException 之类的异常,因为它们是从 HibernateException 扩展而来的。您可以查看转换方法中的异常,这些异常包含在 Hibernate Exceptions 中。

@ExceptionHandler({TransactionSystemException.class})
public ResponseEntity<Object> handleConstraintViolation(TransactionSystemException ex, WebRequest request) {

    if (ex.getCause() instanceof RollbackException) {
       RollbackException rollbackException = (RollbackException) ex.getCause();
         if (rollbackException.getCause() instanceof ConstraintViolationException) {
             return new ResponseEntity<Object>(...);
         }
    ...
    }
    ...

    return new ResponseEntity<Object>(...);
}

推荐阅读