Исключение нарушения ограничений ORA-00001

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

java.sql.BatchUpdateException: ORA-00001: уникальное ограничение (DBSCHEMA.IDX_CO_DETAILS) нарушено.

Я проверил индекс в таблице на предмет имени индекса DBSCHEMA.IDX_CO_DETAILS .

Он не включал ни одного столбца ( INCLUDE_COLUMN имеет значение null) . Как я могу знать, для чего это ограничение? Это ограничение первичного ключа?

Мы используем Hibernate для ORM. Ниже приведен обратный след в контексте гибернации.

Caused by: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)

1 ответ

Решение

Уникальное ограничение обеспечивает, ну, уникальность. Это позволит пустые значения, в отличие от ограничения первичного ключа.

Ваша ошибка означает, что вы вставляете дубликаты данных, когда база данных настроена для явного запрета этого.

Вы можете узнать, какие ограничения существуют для таблицы, выполнив следующий запрос для all_constraints. Ссылка декодирует столбец CONSTRAINT_TYPE, например P является первичным ключом и U уникальный ключ.

select *
  from all_constraints uc
 where uc.table_name = 'MY_TABLE'
   and owner = 'DBSCHEMA'

Чтобы узнать, какие столбцы находятся в ограничении, используйте all_cons_columns вместо этого, или объединяя два в один запрос:

select uc.*, ucc.column_name, ucc.position
  from all_constraints uc
  join all_cons_columns ucc
    on uc.owner = ucc.owner
   and uc.table_name = ucc.table_name
   and uc.constraint_name = ucc.constraint_name
 where uc.table_name = 'MY_TABLE'
   and uc.owner = 'DBSCHEMA'

К любому запросу вы можете добавить дополнительное условие and constraint_name = 'IDX_CO_DETAILS' чтобы выяснить детали конкретного ограничения, которое, кажется, вызывает вашу проблему.


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

Если вы выполните следующий запрос, он должен сообщить вам, существует ли объект в базе данных:

select *
  from all_objects
 where object_name = 'IDX_CO_DETAILS'

Я ожидаю, что OBJECT_TYPE возвращается по этому запросу 'INDEX',

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

select *
  from all_indexes
 where index_name = 'IDX_CO_DETAILS'

Судя по вашей ошибке я бы еще ожидал, что столбец UNIQUNESS возвращается по этому запросу 'UNIQUE',

Это должно помочь вам отследить объект.

Вы также можете использовать системный пакет dbms_metadata отследить DDL объекта; будьте осторожны, это возвращает удар.

select dbms_metadata.get_ddl('INDEX','IDX_CO_DETAILS', schema => 'DBSCHEMA') 
  from dual

параметр schema не является обязательным.

Другие вопросы по тегам