如何在java中处理PSQLException?

时间:2016-10-28 09:11:24

标签: java postgresql exception

我对我的一个实体有一个唯一的约束,每当我遇到违反该约束时发生的PSQLException时,我想回复一个错误的请求。

这是我尝试实现的异常处理程序:

@ControllerAdvice
public class DatabaseExceptionHandler {
    @ExceptionHandler(value = PSQLException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void handleDatabaseExceptions(PSQLException e) {
        // i want to respond with a bad request only when this condition is satisfied
//
//        if (e.getSQLState().equals("23505")) {
//
//        }
    }

}

这就是模型保存在db:

中的地方
 public DepartmentForHoliday setDepartment(DepartmentForHoliday department) {
        if (department.getDepartmentId() == null) {
            Department savedDepartment = new Department();
            savedDepartment.setName(department.getName());
            try {
                departmentRepository.save(savedDepartment);
            } catch (PSQLException e) {
              /*here i have a compiler error which says that this exception is never thrown in the corresponding try block, but where ?*/
            }
}

这是我添加重复条目时抛出的异常:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_1t68827l97cwyxo9r1u6t4p7d"
  Detail: Key (name)=(Tech) already exists.
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2458) ~[postgresql-9.4.1211.jre7.jar:9.4.1211.jre7]

如何处理PSQLExceptions?我应该将自己的异常作为包装器或如何解决这个问题吗?

4 个答案:

答案 0 :(得分:3)

关键问题是PSQLException被包装到一些Spring异常中(我假设你的代码);你必须打开它(例如使用番石榴的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 :)
                }
            }
        }
    }
}

完成此操作后,您可以抛出自定义异常并在DatabaseExceptionHandler

中处理它

答案 1 :(得分:1)

你正在捕捉PSQLException。而不是那样,请抓住SQLException。使用SQLException,您可以处理所有这些SQL异常。

您可以在this link

查看SQLException知识

然后在你的代码中只需要处理SQLException即可。最通用的catch子句如下:

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

使用此代码可以打印异常。如果您想了解更多信息,请查看this

答案 2 :(得分:0)

您也可以直接为该包装异常(@radek提到)注册异常处理程序。

在你的情况下:

convertHibernateAccessException

错误在org.springframework.orm.jpa.vendorHibernateJpaDialect的{​​{1}}内转换, +----------+----------+--------------------+--------------------+--------------------+--------------------+--------------------+ | _created| _updated| name| description| indication| name| patents_patent| +----------+----------+--------------------+--------------------+--------------------+--------------------+--------------------+ |2005-06-13|2016-08-17| Lepirudin|Lepirudin is iden...|For the treatment...| Lepirudin|{"data" : [{"coun...| |2005-06-13|2017-04-27| Cetuximab|Cetuximab is an e...|Cetuximab, used i...| Cetuximab|{"data" : [{"coun...| |2005-06-13|2017-06-14| Dornase alfa|Dornase alfa is a...|Used as adjunct t...| Dornase alfa|{"data" : [{"coun...| |2005-06-13|2016-08-17| Denileukin diftitox|A recombinant DNA...|For treatment of ...| Denileukin diftitox| NULL| |2005-06-13|2017-03-10| Etanercept|Dimeric fusion pr...|Etanercept is ind...| Etanercept|{"data" : [{"coun...| |2005-06-13|2017-07-06| Bivalirudin|Bivalirudin is a ...|For treatment of ...| Bivalirudin|{"data" : [{"coun...| |2005-06-13|2017-07-05| Leuprolide|Leuprolide belong...|For treatment of ...| Leuprolide|{"data" : [{"coun...| |2005-06-13|2017-06-16|Peginterferon alf...|Peginterferon alf...|Peginterferon alf...|Peginterferon alf...|{"data" : [{"coun...| |2005-06-13|2017-06-08| Alteplase|Human tissue plas...|For management of...| Alteplase| NULL| |2005-06-13|2016-12-08| Sermorelin|Sermorelin acetat...|For the treatment...| Sermorelin| NULL| |2005-06-13|2016-08-17| Interferon alfa-n1|Purified, natural...|For treatment of ...| Interferon alfa-n1| NULL| 已经从PSQL处理过了。您可以在那里添加断点并遵循堆栈跟踪。

很多代理都在幕后发生,但需要注意的是,总有一个可读的,富有表现力的异常可以直接使用。

答案 3 :(得分:0)

这已经很晚了,但是基于先前的回答,我能够这样解决:

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;
}

其中UniqueConstraintViolationException是自定义异常,并通过spring控制器建议进行处理。