我对我的一个实体有一个唯一的约束,每当我遇到违反该约束时发生的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?我应该将自己的异常作为包装器或如何解决这个问题吗?
答案 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控制器建议进行处理。