Спящий режим, как предотвратить дублирование записи с сгенерированным идентификатором

Есть ли способ предотвратить дублирование ввода данных с помощью режима гибернации для объектов с автоматически сгенерированным первичным ключом?

Чтобы быть более конкретным, у меня есть постоянный объект в базе данных и временный объект (еще не вставленный в базу данных), и эти два объекта одинаковы в отношении методов equals и hashcode. Но, поскольку идентификатор класса сущностей этих объектов аннотируется аннотацией сгенерированного значения, спящий режим по-прежнему создает новый экземпляр для временного объекта в базе данных. В результате в базе данных есть повторяющиеся записи (в отношении методов equals и hashcode) с разными первичными ключами.

Да, я знаю, что если я сделаю ПК не сгенерированным автоматически, если я использую UUID, то я достигну своей цели. Но я просто хочу спросить, почему методы equals и hashcode не работают для сущностей с автоматически сгенерированным первичным ключом? Или я что-то не так делаю?


person serenitytr    schedule 24.03.2011    source источник


Ответы (3)


почему методы equals и hashcode не работают

Hibernate не учитывает здесь equals()/hashCode(), потому что нет эффективных способов сделать это.

Как Hibernate может проверить, что объект с таким же идентификатором (с точки зрения equals()) уже существует в базе данных? Поскольку equals() может содержать произвольные условия, Hibernate не может превратить его в SQL-запрос, так что единственный способ проверить это — загрузить все объекты в память и вызвать для них equals(), чтобы сравнить их с объектом, который вы собираетесь сохранить.

Поэтому Hibernate использует первичные ключи для определения идентичности объектов.

Или я что-то не так делаю?

Непонятно, чего вы собираетесь добиться. Если вы хотите, чтобы Hibernate обновлял объекты в базе данных состоянием объектов, которые вы передаете, вам нужно использовать merge().

См. также:

person axtavt    schedule 24.03.2011

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

person Soronthar    schedule 24.03.2011

Примените ограничение на уровне БД. Без этого трудно (невозможно?) избежать дубликатов, особенно если ваше приложение кластеризовано.

person Adisesha    schedule 24.03.2011