Как получить данные, вызвавшие нарушение уникального ограничения (через Hibernate)?

Есть ли способ узнать, какая запись вызвала такое нарушение в Hibernate?

Обычно вы добавляете объекты в сеанс и в конце сохраняете их. Если возникает такая ошибка, требуется некоторое время, чтобы отследить, какая запись нарушила ограничение.

Есть ли способ узнать, какая запись вызвала (либо toString() в случае новых объектов, либо первичный ключ в случае существующих объектов, должен значительно упростить процесс отладки.

Спасибо.


org.hibernate.exception.ConstraintViolationException: could not insert: [com.project.valueobject.mapping.Model]
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:40)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2163)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2643)
    at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:51)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:298)
    at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181)
    at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:94)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)

person lud0h    schedule 20.10.2009    source источник


Ответы (3)


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

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

person NT_    schedule 20.10.2009
comment
У нас уже есть перехватчики аудита, но когда список большой, то не так просто отследить, какой из элементов вызвал ошибку. Кстати, мы используем Oracle. - person lud0h; 20.10.2009
comment
Возможно, этот пост пригодится: technicalpickles.com/posts/ - person NT_; 20.10.2009

Я просто устанавливаю точку останова в AbstractEntityPersister::performInsert(...), чтобы найти оскорбительную запись.

Как сказал _NT, возможно, MySQL поддерживает это, но не Oracle.

Но будет держать это открытым, чтобы узнать любое элегантное решение.

person lud0h    schedule 21.10.2009
comment
Почему прослушиватели событий не элегантны? - person NT_; 23.10.2009
comment
Как я объяснил в своем комментарии выше, пока я не попытаюсь «сохранить», я не буду говорить об ограничении, а потом уже слишком поздно. Я искал что-то вроде того, что вы сказали о «MySQL», возможно, виноват Oracle :-) - person lud0h; 13.11.2009
comment
Ну, не уверен, почему Oracle не регистрирует это - интересно, сколько человеко-тысячелетий тратится впустую ежегодно из-за этого ..? - person nsandersen; 15.05.2017

При использовании уровня журнала TRACE отображаются значения всех параметров, которые передаются в базу данных.

person SDev    schedule 04.05.2010