Мы пытаемся объединить объекты после того, как было создано исключение StaleObjectStateException, чтобы сохранить объединенную копию.
Вот наша ситуация с окружающей средой:
- Элемент списка
- Мульти-пользовательская система
- Настольное приложение WPF, база данных SQL Server 2008
- NHibernate 3.1.0.4000, FluentNHibernate 1.2.0.712
- Глобальные, длительные сеансы NHibernate [на данный момент.Мы понимаем, что сеанс для каждого докладчика является рекомендуемым шаблоном, но в настоящее время в нашем расписании проекта нет времени для преобразования.]
- Сохранения сверху вниз и навигация по свойствам (то есть мы сохраняемобъект уровня (в данном документе называемый родительским) в нашем доменном графе)
- .Cascade.AllDeleteOrphan () используется в большинстве случаев.
- Пользователи владеют только некоторыми объектами в графе домена, но разделяют права собственности наParent.
- Свойства навигации для дочерних объектов не существуют.
- Все классы имеют числовой идентификатор и числовые поля версии.
Вариант использования:
- Пользователь 1 запускает приложение и открывает Parent.
- Пользователь 2 запускает приложение и открывает Parent.
- Пользователь 2 добавляет дочерний элемент (в данном документе C2).
- Пользователь 2save Parent.
- Пользователь 1 добавляет дочерний элемент (в данном случае C1).
- Пользователь 1 сохраняет Parent.
- Пользователь 1 получает исключение StaleObjectStateException (и это правильно)
Мы хотим Изящно обработать исключение.Поскольку пользователи разделяют права собственности на родителя, пользователь 1 должен иметь возможность успешно сохранить и сохранить родителя как со своим новым дочерним элементом, так и с дочерним элементом пользователя 2.
Когда выбрасывается SOSE, согласно Айенде (http://msdn.microsoft.com/en-us/magazine/ee819139.aspx):
ваш сеанс и его загруженные объекты являются тостами, потому что с NHibernate исключение, выброшенное из сеанса, переводит этот сеанс в неопределенное состояние. Вы больше не можете использовать этот сеанс или любые загруженные объекты
C1 уже был назначен идентификатор и версия # в сеансе, который теперь бесполезен. (Хотелось бы, чтобы это было не так.)
Как мы комбинируем использование ISession.Merge () и ISession.Refresh () для получения недавно сохраненного Parent с C1 и C2?
Мы пробовали несколько загадочных перестановок, ни одна из которых не работает полностью. Обычно, любая строка былаобновлен или удален другой транзакцией (или сопоставление несохраненного значения было неверным), или фактическим конфликтом идентификаторов на уровне ODBC.
Наша теория на данный момент:
- Сброс номеров версий на С1 (чтобы предотвратить «неверное сопоставление несохраненных значений»)
- Получить новый сеанс
- newSession.Refresh (C1);
- newParent= newSession.QueryOver [...]
- newParent.Add (C1);
- newSession.SaveOrUpdate (newParent)
Однако во всей документации предполагается, чтоnewSession.Merge предполагается достаточным.
Другие сообщения, используемые в качестве исследования: Свободный NHibernate Newbie: строка была обновлена или удалена другой транзакцией Есть ли альтернатива ISession.Merge (), которая не генерируется при использовании оптимистической блокировки? Строка StaleObjectstateException была обновлена или удалена Как я могу сказать NHibernate сохранять только измененные свойства Hibernate (JPA): как обрабатывать StaleObjectStateException, когда несколько объектов были изменены и зафиксированы (Java, но я думаю, что это актуально)