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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3502279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:21:28  来源:igfitidea点击:

How to handle JPA unique constraint violations?

javaexceptionjpaexception-handlingconstraints

提问by deamon

When a unique constraint is violated, a javax.persistence.RollbackExceptionis thrown. But there could be multiple reasons to throw a RollbackException. How can I find out that a unique constraint was violated?

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

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

采纳答案by Pascal Thivent

How can I find out that a unique constraint was violated?

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

Exception are chained, you have to call getCause()recursively to get the provider specific exception (and maybe go down to the SQLException) to translate it into something your application can handle nicely for your user. The following will print the chain of exception:

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

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

For the exception handling and the "translation", you could do something like what Spring does (see the various JpaDialectclasses, e.g. HibernateJpaDialectto get an idea).

对于异常处理和“翻译”,您可以做一些类似于 Spring 所做的事情(请参阅各种JpaDialect类,例如HibernateJpaDialect获得一个想法)。

All this is not nice, this code won't be portable and finding what attribute(s) caused the violation won't be easy. This somehow confirms that there is no elegant and portable way to handle constraint violations in JPA.

所有这些都不好,此代码不可移植,并且查找导致违规的属性并不容易。这在某种程度上证实了在 JPA 中没有优雅且可移植的方法来处理约束冲突

回答by Aaron Digulla

Use e.getCause()to examine what caused the rollback.

使用e.getCause()来检查什么引起的回滚。

回答by hakish

i think printing the stack trace will help you to know this. e.printStackTrace();

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

回答by Mercy

You can do like this :

你可以这样做:

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.

And then view the information of exception.

然后查看异常信息。

回答by abhijitcaps

compiler returns the exception SQLIntegrityConstraintViolationException, while trying to violate unique constraint.

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

Use the following catch block concept, to handle proper exceptions.

使用以下 catch 块概念来处理适当的异常。

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

回答by AaMng

You can use the following :

您可以使用以下内容:

If you are using spring framework then you can use :

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

org.springframework.dao.DataIntegrityViolationException

org.springframework.dao.DataIntegrityViolationException

If standard JPA following can be used

如果可以使用以下标准 JPA

org.hibernate.exception.ConstraintViolationException

org.hibernate.exception.ConstraintViolationException

At sql level following can be used :

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

java.sql.SQLIntegrityConstraintViolationException

java.sql.SQLIntegrityConstraintViolationException

回答by AjayPS

This might very late for you but here's how I solved it for PostGres.

这对你来说可能很晚了,但这是我为 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);

        }