2010-05-23 4 views
11

Рассмотрим следующий класс сущностей, используемый, например, с EclipseLink 2.0.2, где атрибут link не является первичным ключом, но уникальным, тем не менее.Нарушение ограничений ограничения в JPA 2.0

@Entity 
public class Profile { 
    @Id 
    private Long id; 

    @Column(unique = true) 
    private String link; 

    // Some more attributes and getter and setter methods 
} 

Когда я вставляю записи с дублирующим значением атрибута link, EclipseLink не бросает EntityExistsException, но бросает DatabaseException, с сообщением, пояснив, что ограничение уникальности было нарушено.

Это не кажется очень полезным, так как не было бы простого независимого от базы данных способа поймать это исключение. Каким был бы способ справиться с этим?

Несколько вещей, которые я Рассматриваемые:

  • Проверка кода ошибки на DatabaseException - Я боюсь, что этот код ошибки, хотя, нативный код ошибки для базы данных;
  • Проверка наличия Profile с определенным значением для link - это, очевидно, приведет к огромному количеству излишних запросов.
+0

Я представил ошибку для этой проблемы. Пожалуйста, проголосуйте за него, чтобы мы могли устранить эту проблему: https://bugs.eclipse.org/bugs/show_bug.cgi?id=375745 – sdoca

ответ

5

Когда я вставляю записи с дублирующим значением атрибута ссылки, EclipseLink не бросает EntityExistsException

Да и провайдер JPA не должен бросать в этом случае в EntityExistException, вы не получите EntityExistException на чем-то еще, чем на первичный ключ.

(...), но генерирует исключение DatabaseException с сообщением о том, что было нарушено уникальное ограничение.

Это очень НЕПРАВИЛЬНО от EclipseLink, поставщик JPA должен бросить PersistenceException или подкласс, но конечно не конкретное исключение, как o.e.p.e.DatabaseException. Это ошибка, и мне следует сообщить об этом, как я уже упоминал в previous answer.

Это не кажется очень полезным, так как не было бы простого независимого от базы данных способа поймать это исключение. Каким был бы способ справиться с этим?

Тот же ответ, что и выше, см. Мой previous answer.

+0

Так как вы упоминаете EclipseLink, в частности здесь: знаете ли вы о других провайдерах JPA, которые ведут себя правильно ? – Hank

+0

@Hank Возможно, проблема исправлена ​​в последних версиях, не могу сказать. Но, насколько мне известно, Hibernate в таком случае выбрасывает «PersistenceException». –

2

Очень жаль, что они не имеют исключения ConstraintViolationException в JPA. Я создал вспомогательный метод, чтобы определить, является ли PersistenceException нарушением ограничения для данного класса - это только спящий режим. Я предполагаю, что есть способ сделать это, используя другие реализации.

protected Boolean isUniqueConstraintViolation(PersistenceException ex, Class entity) { 

    if (((NonUniqueObjectException)ex.getCause()).getEntityName().equals(entity.getName())) { 
     return true; 
    } 

    return false; 
} 
Смежные вопросы