Нарушено уникальное ограничение из-за слишком большого значения для столбца (Oracle) - PullRequest
0 голосов
/ 14 июня 2019

Возможно ли получить

ORA-00001: уникальное ограничение (XXX) нарушено

из-за

ORA-12899: слишком большое значение для столбца (XXX)

в базе данных оракула с использованием Hibernate (как указано в на этой странице слияния )?

(столбцы для каждой ошибки находятся в разных таблицах, но связаны друг с другом)

В таком случае, как это возможно?

* ОБНОВЛЕНИЕ *

Я могу подтвердить причинно-следственную связь между исключениями. Данный сценарий выглядит следующим образом:

Число процессов, которые выполняют различные операции с базой данных. Эти операции суммируются до сброса сеанса Hibernate. Когда вы вызываете метод flush, запросы выполняются в одной транзакции.

В моем конкретном случае у меня есть объекты A и B, которые оба имеют внутри объекта C (ссылка на объект одинакова, для каждого родительского объекта копия отсутствует). Когда программа пытается сохранить A (со слишком большим строковым полем), сначала выполняется запрос вставки C, а затем вставка в сам объект, что приводит к «ORA-12899: значение слишком велико для столбца». На данный момент C находится в базе данных, но еще не зафиксирован. Затем следующий процесс пытается сохранить B, который содержит объект C, и это приводит к «ORA-00001: уникальное ограничение нарушено» на объекте C.

Мои вопросы:

  • Когда у первого процесса нет ошибок (без слишком большого столбца), второй не пытается снова вставить C, только сделать вставку в сущность B (возможно, отсоединенное состояние сущности C?).
  • Почему выполнение не прерывается при первой ошибке?

1 Ответ

0 голосов
/ 19 июня 2019

Оба исключения (уникальное ограничение и слишком большое значение для столбца) связаны между собой.Есть несколько процессов, выполняемых в одной транзакции.Эти процессы делают вызовы методов save () или saveOrUpdate (), стекая запросы до тех пор, пока flush () сеанса Hibernate или не завершат транзакцию.

В какой-то момент flush () сеанса вызывается с помощьюданный сценарий:

Объект A и B оба содержат одинаковую ссылку на объект C. Первый процесс пытается вставить объект A, поэтому сначала выполняет вставку C без проблем, позже пытается вставить A, но происходит сбой из-заисключение слишком большого столбца.В этот момент C находится в базе данных (еще не зафиксирован), но сеанс гибернации находится в некогерентном состоянии из-за предыдущего сбоя, и Hibernate не знает о вставляемом C (сбой при сбросе сеанса не вызывает откат, является ответомразработчик).

Затем выполняется второй процесс и пытается вставить B в базу данных.Если предыдущий процесс прошел нормально, Hibernate вставляет только объект B, потому что он знает, что C уже находится в базе данных.Из-за непоследовательного состояния сеанса Hibernate пытается снова сохранить объект C в базе данных, вызывая исключение уникального ограничения.

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