如何处理JPA唯一约束违规?

时间:2010-08-17 12:18:35

标签: java exception jpa exception-handling constraints

违反唯一约束时,会抛出javax.persistence.RollbackException。但抛出RollbackException可能有多种原因。如何才能发现违反了唯一约束?

try {
    repository.save(article);
}
catch(javax.persistence.RollbackException e) {
    // how to find out the reason for the rollback exception?
}

8 个答案:

答案 0 :(得分:19)

  

如何才能发现违反了唯一约束?

异常是链接的,您必须递归调用getCause()以获取提供程序特定的异常(并且可能转到SQLException)将其转换为您的应用程序可以很好地为您的用户处理的内容。以下将打印异常链:

for (t = e.getCause(); t != null; t = t.getCause()) {
    logger.debug("Exception:" + t);
}

对于异常处理和“翻译”,你可以做一些像Spring那样的事情(参见各种JpaDialect类,例如HibernateJpaDialect来获得一个想法)。

所有这些都不好,这段代码不可移植,找到导致违规的属性并不容易。这以某种方式证实没有elegant and portable way to handle constraint violations in JPA

答案 1 :(得分:3)

使用e.getCause()检查导致回滚的原因。

答案 2 :(得分:2)

编译器在尝试违反唯一约束时返回异常 SQLIntegrityConstraintViolationException

使用以下catch块概念来处理正确的异常。

catch(SQLIntegrityConstraintViolationException e) 
{
  // Error message for integrity constraint violation
}
catch(Exception e)
{
 // Other error messages
}

答案 3 :(得分:2)

您可以使用以下内容:

如果您使用的是spring框架,那么您可以使用:

org.springframework.dao.DataIntegrityViolationException

如果可以使用以下标准JPA

org.hibernate.exception.ConstraintViolationException

在sql级别可以使用以下内容:

java.sql.SQLIntegrityConstraintViolationException

答案 4 :(得分:1)

这可能对您来说很晚了,但这是我为PostGres解决的方法。

catch (DataIntegrityViolationException e) {

            for (Throwable t = e.getCause(); t != null; t = t.getCause()) {

                if (PSQLException.class.equals(t.getClass())) {
                    PSQLException postgresException = (PSQLException) t;

                    // In Postgres SQLState 23505=unique_violation
                    if ("23505".equals(postgresException.getSQLState())) {
                        throw new CustomDataAlreadyExistsException("YourErrorCode", e);
                    }
                }
            }
            throw new SomeOtherException("YourErrorCode2", e);

        }

答案 5 :(得分:0)

我认为打印堆栈跟踪可以帮助您了解这一点。 e.printStackTrace();

答案 6 :(得分:0)

你可以这样做:

StringWriter writer=new StringWriter(); //remains the message from stack trace.
e.printStackTrace(new PrintWriter(writer));
String message=writer.toString(); // gets the message of full stack trace.

然后查看异常信息。

答案 7 :(得分:0)

您必须捕获javax.persistence.PersistenceException。 被抛出的异常是org.hibernate.exception.ConstraintViolationException。

异常消息:org.hibernate.exception.ConstraintViolationException:密钥“ nic_account_no”的条目“ 893073116V-1234567”重复

相关问题