How to handle a PSQLException in java?

后端 未结 4 933
孤街浪徒
孤街浪徒 2021-02-09 08:43

I have a unique constraint on one of my entities and whenever I get a PSQLException which occurs whenever that constraint is violated, I want to respond with a bad request.

相关标签:
4条回答
  • 2021-02-09 09:13

    You are catching PSQLException. Instead of that, please catch SQLException. With SQLException you will can handle all this SQL exceptions.

    You can check the SQLException knowledge at this link

    Then in your code just treat the SQLException as you want. The most generic catch clause is the following one:

        catch (SQLException e)
       {
       System.out.println("ERROR: Fetch statement failed: " +
          e.getMessage());
       }
    

    With this code you are printing the exception. If you want more information, check this

    0 讨论(0)
  • 2021-02-09 09:16

    You might as well register an exception handler for that wrapped exception (that @radek mentioned) directly.

    In your case that's:

    @ExceptionHandler(DataIntegrityViolationException::class)
    protected fun handleDataIntegrityException(ex: DataIntegrityViolationException, request: WebRequest) : ResponseEntity<SomeBody>{
        return ResponseEntity.badRequest().body(someBodyHere)
    }
    

    The error is converted within convertHibernateAccessException in org.springframework.orm.jpa.vendorHibernateJpaDialect, which has already processed away from PSQL. You can add a breakpoint there and follow the stacktrace.

    There is a lot of proxy'ing happening under the hood, but the takeaway is that there is always a readable, expressive Exception to use directly.

    0 讨论(0)
  • 2021-02-09 09:23

    Key problem is that PSQLException is wrapped into some Spring exception (which I assume from your code); you have to unwrap it (for example using guava's Throwables):

    public DepartmentForHoliday setDepartment(DepartmentForHoliday department) {
        if (department.getDepartmentId() == null) {
            Department savedDepartment = new Department();
            savedDepartment.setName(department.getName());
            try {
                departmentRepository.save(savedDepartment);
            } catch (RuntimeException e) {
                Throwable rootCause = com.google.common.base.Throwables.getRootCause(e);
                if (rootCause instanceof SQLException) {
                    if ("23505".equals(((SQLException) rootCause).getSQLState())) {
                        // do smth interesting :)
                    }
                }
            }
        }
    }
    

    Once you do that you can throw your custom exception and handle it in DatabaseExceptionHandler

    0 讨论(0)
  • 2021-02-09 09:32

    This is quite late, but building on previous responses I was able to solve it as so:

    try {
        return this.projectRepository.saveAndFlush(patchedProjectEntity);
    } catch (DataIntegrityViolationException e) {
        if (e.getMostSpecificCause().getClass().getName().equals("org.postgresql.util.PSQLException") && ((SQLException) e.getMostSpecificCause()).getSQLState().equals("23505"))
            throw new UniqueConstraintViolationException("", e.getMostSpecificCause());
        throw e;
    }
    

    Where UniqueConstraintViolationException is a custom exception and handled with a spring controller advice.

    0 讨论(0)
提交回复
热议问题