Вам потребуется проанализировать сообщение об исключении, чтобы извлечь имя ключа, вызвавшего исключение. Когда у вас есть имя индекса в руке, вы сможете распознать, какой тип индекса он основан на соглашениях об именах или на основе метаданных о вашей схеме базы данных.
Вот несколько примеров из некоторых журналов, которые мне пригодятся:
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 или модуля персистентности.