В Hibernate / JPA как определить, является ли ConstraintViolationException PK, FK или нарушением уникального ключа? - PullRequest
1 голос
/ 10 марта 2019

Я разрабатываю универсальный метод с универсальной обработкой для сохранения сущности в базе данных, однако мне сложно узнать, является ли ConstraintViolationException нарушением первичного ключа, внешнего ключа или уникального ключа

public Collection<T> salvar(final Collection<T> e) {        
        try {
            return dao.salvar(e);
        } catch (ConstraintViolationException e1) {
            if (PK_violation) {
                handle PK error 
            } else if (FK_violation) {
                handle FK error
            }
        }

    }

Как узнать, какой тип нарушения является моим исключением (PK_violation или FK_violation)?

Спасибо

1 Ответ

1 голос
/ 10 марта 2019

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

Вот несколько примеров из некоторых журналов, которые мне пригодятся:

Duplicate entry '1023' for key 'PRIMARY'
Duplicate entry 'test-user-817fe6b0-587a-4003-9dec-8d2ea8f87cad' for key 'UKwqsqlvajcne4rlyosglqglhk'

Первый случай - это нарушение первичного ключа. Кажется, что в этом случае отображается имя «PRIMARY». Второе - это нарушение уникального ключа - в нашем случае наши уникальные имена ключей начинаются с "UK", поэтому мы можем использовать это, чтобы определить, был ли нарушен тот тип индекса.

Итак, примените регулярное выражение к e1.getMessage() с группой для имени ключа, извлеките значение этой группы, примените другое регулярное выражение или другую бизнес-логику, чтобы определить, с каким типом индекса вы имеете дело, основываясь на ваших локальных соглашениях об именах. или запросив у базы данных информацию об индексе.

Вы можете запросить базу данных для получения информации о природе индекса, упомянутого в исключении. Если вы собираетесь использовать запрос к базе данных, вы можете выполнить один запрос при запуске, чтобы собрать метаданные обо всех индексах и использовать эти кэшированные данные для остальной части прогона.

Если вы используете аннотированные Java-классы для определения отображения JPA, вы можете использовать эти аннотации (возможно, с процессором аннотаций или во время выполнения с помощью отражения) для извлечения информации об индексах. В частности, аннотация javax.persistence.Id приводит к первичному ключу, а javax.persistence.Table имеет атрибут uniqueConstraints, который использует javax.persistence.UniqueConstraint для определения уникальных ограничений. Попытка сделать это во время обработки исключений будет затруднена, потому что вы, вероятно, не сможете выяснить, какой объект сущности вызвал нарушение - в общем случае многие сущности сбрасываются в базу данных одновременно; Я не знаю, как определить, какой из них вызвал проблему.

Мне неизвестно о каком-либо API JPA, который позволит вам извлечь эту информацию из EntityManager или модуля персистентности.

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