Как обработать JPA уникальные нарушения ограничений? - PullRequest
23 голосов
/ 17 августа 2010

При нарушении уникального ограничения выдается javax.persistence.RollbackException.Но может быть несколько причин, чтобы бросить RollbackException.Как я могу узнать, что уникальное ограничение было нарушено?

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

Ответы [ 7 ]

19 голосов
/ 18 августа 2010

Как я могу узнать, что уникальное ограничение было нарушено?

Исключение связано, вы должны вызвать getCause() рекурсивно, чтобы получить исключение для конкретного провайдера (и, возможно, выйтина SQLException), чтобы перевести его в то, что ваше приложение может хорошо обработать для вашего пользователя.Далее будет напечатана цепочка исключений:

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

Для обработки исключений и «перевода» вы можете сделать что-то наподобие того, что делает Spring (см. Различные классы JpaDialect, например, HibernateJpaDialect, чтобы понять).

Все это нехорошо, этот код не будет переносимым, и поиск атрибутов, вызвавших нарушение, будет непростым делом.Это как-то подтверждает, что в JPA .

не существует элегантного и портативного способа обработки нарушений ограничений.
3 голосов
/ 17 августа 2010

Используйте e.getCause(), чтобы проверить, что вызвало откат.

2 голосов
/ 12 апреля 2018

Вы можете использовать следующее:

Если вы используете пружинный каркас, вы можете использовать:

org.springframework.dao.DataIntegrityViolationException

Если можно использовать стандартное JPA, следующее

org.hibernate.exception.ConstraintViolationException

На уровне sql может использоваться следующее:

java.sql.SQLIntegrityConstraintViolationException

2 голосов
/ 01 мая 2013

компилятор возвращает исключение SQLIntegrityConstraintViolationException при попытке нарушить ограничение уникальности.

Используйте следующую концепцию блока catch для обработки правильных исключений.

catch(SQLIntegrityConstraintViolationException e) 
{
  // Error message for integrity constraint violation
}
catch(Exception e)
{
 // Other error messages
}
1 голос
/ 10 августа 2018

Это может быть очень поздно для вас, но вот как я решил это для 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);

        }
0 голосов
/ 17 августа 2010

Вы можете сделать так:

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.

А затем просмотреть информацию об исключении.

0 голосов
/ 17 августа 2010

Я думаю, печать трассировки стека поможет вам узнать это. e.printStackTrace ();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...