Существует ограничение базы данных UNIQUE для индекса, которое не позволяет иметь более одной записи с одинаковыми столбцами.
Есть фрагмент кода, управляемый Hibernate (v2.1.8), выполняющий два DAO getHibernateTemplate().save( theObject )
вызовы, результатом которых являются две записи, внесенные в указанную выше таблицу.
Если этот код выполняется без транзакций, он приводит к INSERT, UPDATE, затем к другим SQL-операторам INSERT и еще одному UPDATE и работает нормально. Очевидно, последовательность состоит в том, чтобы сначала вставить запись, содержащую DB NULL, а затем обновить ее соответствующими данными.
Если этот код выполняется в Spring (v2.0.5), заключенный в одну транзакцию Spring, он приводит к двум INSERTS, за которыми следует немедленное исключение из-за ограничения UNIQUE, упомянутого выше.
Эта проблема проявляется только в MS SQL из-за его несовместимости с ANSI SQL. Он отлично работает с MySQL и Oracle. К сожалению, наше решение кроссплатформенное и должно поддерживать все базы данных.
Какой способ решения данной проблемы вы бы предпочли, имея этот стек технологий?
Поведение ANSI заключается в том, что NULL = NULL не соответствует действительности, поэтому в ограничении уникальности должно быть разрешено два значения NULL.




У меня нет опыта работы с Hibernate, поэтому я не знаю, можете ли вы изменить БД по своему желанию или для Hibernate требуется определенная структура БД, которую вы не можете изменить.
Если вы можете внести изменения, вы можете использовать этот обходной путь в MSSQL для эмуляции поведения ANSI:
удалить уникальный индекс / ограничение
определите поле calc следующим образом:
alter table MyTable Add MyCalcField as
case when MyUniqueField is NULL
then cast(Myprimarykey as MyUniqueFieldType)
else MyUniqueField end
добавьте уникальное ограничение для этого нового поля, которое вы создали.
Естественно, это применимо, если MyUniqueField не является первичным ключом! :)
Вы можете найти более подробную информацию в эта статья на databasejournal.com
Вы можете попробовать сбросить сеанс гибернации между двумя сохранениями. Это может заставить Hibernate выполнить первое обновление перед второй вставкой.
Кроме того, когда вы говорите, что спящий режим вставляет NULL с помощью вставки, вы имеете в виду, что каждый столбец имеет значение NULL или только столбец идентификатора?
Из любопытства, какое поведение ANSI SQL определяет в этом случае? Кажется, что вставка двух одинаковых строк в таблицу с уникальным ограничением приведет к нарушению ограничения.