Обходной путь для Spring / Hibernate из-за нестандартного поведения ограничения UNIQUE в MS SQL - PullRequest
3 голосов
/ 25 сентября 2008

Существует ограничение базы данных UNIQUE для индекса, которое не допускает более одной записи с одинаковыми столбцами.

Существует фрагмент кода, управляемый Hibernate (v2.1.8), выполняющий два DAO
getHibernateTemplate().save( theObject )
вызовы, в результате которых две таблицы заносятся в таблицу, указанную выше.

Если этот код выполняется без транзакций, он вызывает INSERT, UPDATE, затем другой INSERT и другие операторы SQL UPDATE и работает нормально. Очевидно, последовательность состоит в том, чтобы сначала вставить запись, содержащую БД NULL, а затем обновить ее соответствующими данными.

Если этот код выполняется в Spring (v2.0.5), заключенном в одну транзакцию Spring, он приводит к двум INSERTS, за которыми следует немедленное исключение из-за ограничения UNIQUE, упомянутого выше.

Эта проблема проявляется только на MS SQL из-за ее несовместимости с ANSI SQL. Отлично работает на MySQL и Oracle. К сожалению, наше решение является кроссплатформенным и должно поддерживать все базы данных.

Имея этот стек технологий, какой бы вы предпочли обходной путь для данной проблемы?

Ответы [ 2 ]

1 голос
/ 28 сентября 2008

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

Кроме того, когда вы говорите, что hibernate вставляет NULL вместе со вставкой, вы имеете в виду, что каждый столбец имеет значение NULL или только столбец идентификатора?

0 голосов
/ 26 сентября 2008

У меня нет опыта работы с 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

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