【问题标题】:How to get the constraint name in a org.springframework.dao.DataIntegrityViolationException?如何在 org.springframework.dao.DataIntegrityViolationException 中获取约束名称?
【发布时间】:2011-08-18 16:52:54
【问题描述】:

在我的应用程序中,当提出违规键时,我想获取约束名称,但我没有找到任何方法来获取此信息。 “getMessage()”返回的消息非常概括,我需要有关错误的更多信息,以便为最终用户提供可自定义的错误消息。

堆栈跟踪:

84732 [http-8080-1] WARN  org.hibernate.util.JDBCExceptionReporter  - SQL Error: 0, SQLState: 23505
84732 [http-8080-1] ERROR org.hibernate.util.JDBCExceptionReporter  - ERROR: duplicate key value violates unique constraint "ix_tb_oferta_vaga"
  Detalhe: Key (cd_pj, cd_curso)=(680, 29) already exists.
187405 [http-8080-1] WARN  org.hibernate.util.JDBCExceptionReporter  - SQL Error: 0, SQLState: 23505
187405 [http-8080-1] ERROR org.hibernate.util.JDBCExceptionReporter  - ERROR: duplicate key value violates unique constraint "ix_tb_oferta_vaga"
  Detalhe: Key (cd_pj, cd_curso)=(680, 29) already exists.

getMessage():

could not insert: [br.gov.ce.seduc.estagio.model.bean.OfertaVaga]; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [br.gov.ce.seduc.estagio.model.bean.OfertaVaga]

谢谢。

亚瑟

【问题讨论】:

    标签: java hibernate spring


    【解决方案1】:

    像这样插入catch 语句:

    catch (DataIntegrityViolationException e) {
            String message = e.getMostSpecificCause().getMessage();
    }
    

    【讨论】:

    • 这将返回格式为ERROR: duplicate key value violates unique constraint "uk_meb3tm159kt0clyot5mmv8oht" Detail: Key (organization_name)=(Villa College QI Campus) already exists. 的字符串。如果他们想为最终用户提供消息,这将无济于事
    • 我认为我们需要注意的唯一部分是提供有意义的唯一约束名称,然后它看起来像:ERROR: duplicate key value violates unique constraint "unique_organization_name" Detail: Key (organization_name)=(Villa College QI Campus) already exists.
    【解决方案2】:

    包装异常通常有办法将原始异常嵌套在其中。对于 Hibernate,您的 ConstraintViolationException 是一个 JDBCException,它有一个名为 getSQLException 的方法,它返回实际的异常。因此,在 Spring DataIntegrityViolationException 上调用 getCause(以获取 Hibernate 异常),对其调用 getSQLException,最后在 SQLException 上调用 getMessage()。该消息应该与您看到的 Hibernate JDBCExceptionReporter 记录的消息相同,如果您只需要约束名称,则必须解析字符串。

    【讨论】:

      【解决方案3】:

      如果您使用的是 PostgreSQL,并且您真的有兴趣查找异常的详细原因,那么您可以在编译时使用 PostgreSQL,如下所示:

      <dependency>
          <groupId>org.postgresql</groupId>
          <artifactId>postgresql</artifactId>
          <!--<scope>runtime</scope>-->
      </dependency>
      

      这样,您将拥有实用程序方法和 PSQLException 类。有了这个,现在您可以将最具体的原因归咎于它。

      var exceptionCause = exception.getMostSpecificCause();
      
      if (exceptionCause instanceof PSQLException psqlException) {
          var serverErrorMessage = psqlException.getServerErrorMessage();
      
          if (serverErrorMessage != null) {
              var detail = serverErrorMessage.getDetail();
              exceptionCause = new Exception(detail);
          }
      }
      

      如您所见,现在您可以抛出或处理此exceptionCause,它将包含您的详细或人类可读的消息。

      【讨论】:

        猜你喜欢
        • 2011-10-14
        • 1970-01-01
        • 2017-06-22
        • 2014-12-13
        • 2011-07-11
        • 2010-09-24
        • 2014-02-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多