Как изящно объединить графы объектов после NHibernate StaleObjectStateException?

Мы пытаемся объединить объекты после того, как было создано исключение StaleObjectStateException, чтобы сохранить объединенную копию.

Вот наша ситуация с окружающей средой:

  • Элемент списка
  • Многопользовательская система
  • Настольное приложение WPF, база данных SQL Server 2008
  • NHibernate 3.1.0.4000, FluentNHibernate 1.2.0.712
  • Global, long- запущенные сеансы NHibernate [на данный момент. Мы понимаем, что сеанс на докладчика является рекомендуемым шаблоном, но в настоящее время у нас нет времени на преобразование в расписании нашего проекта.]
  • Нисходящие сохранения и навигация по свойствам (то есть мы сохраняем объект верхнего уровня ( здесь называется Parent) в нашем графе домена)
  • .Cascade.AllDeleteOrphan () используется в большинстве случаев.
  • Пользователи являются исключительными владельцами некоторых объектов в графе домена, но разделяют владение Родителем.
  • Свойства навигации для дочерних объектов не существуют.
  • Все классы имеют числовой идентификатор и числовые поля версии.

Пример использования:

  • Пользователь 1 запускает приложение и открывает родительский.
  • Пользователь 2 запускает приложение и открывает родительский.
  • Пользователь 2 добавляет ребенка (здесь C2).
  • Пользователь 2 сохраняет Родителя.
  • Пользователь 1 добавляет ребенка (здесь C1).
  • Пользователь 1 сохраняет Родителя.
  • Пользователь 1 получает StaleObjectStateException (и это правильно)

Мы хотим корректно обработать исключение. Поскольку пользователи разделяют владение родительским элементом, Пользователь 1 должен иметь возможность успешно сохранять и сохранять родительский элемент вместе с его новым дочерним элементом и дочерним элементом пользователя 2.

Когда вызывается SOSE, согласно Айенде ( http://msdn.microsoft.com/en-us/magazine/ee819139.aspx ):

ваш сеанс и его загруженные объекты всплывают. , потому что с NHibernate исключение, выброшенное из сеанса, переводит этот сеанс в неопределенное состояние.Вы больше не можете использовать этот сеанс или какие-либо загруженные объекты

C1 уже был назначен идентификатор и номер версии в сеансе, который сейчас не используется. (Хотелось бы, чтобы этого не было.)

Как совместить использование ISession.Merge () и ISession.Refresh (), чтобы получить только что сохраненного Родителя, у которого есть как C1, так и C2?

Мы попробовали количество тайных перестановок, ни одна из которых не работает полностью. Обычно либо «строка была обновлена ​​или удалена другой транзакцией (или отображение несохраненных значений было неверным», либо фактическая коллизия идентификаторов на уровне ODBC.

] Наша теория на данный момент:

  1. Сбросить номера версий на C1 (чтобы предотвратить «неверное отображение несохраненных значений»)
  2. Получить новый сеанс
  3. newSession.Refresh (C1);
  4. newParent = newSession.QueryOver [...]
  5. newParent.Add (C1);
  6. newSession.SaveOrUpdate (newParent)

Однако вся документация предполагает, что newSession.Merge предполагается как достаточно.

Другие сообщения, использованные в качестве исследования:
Fluent NHibernate Newbie: строка была обновлена ​​или удалена другой транзакцией
Есть ли альтернатива ISession.Merge (), которая не срабатывает, когда используя оптимистичную блокировку g?
Строка StaleObjectstateException была обновлена ​​или удалена
Как я могу указать NHibernate сохранять только измененные свойства
Hibernate (JPA): как обработать StaleObjectStateException, когда несколько объектов были изменены и зафиксированы (java , но, думаю, актуально)

9
задан Community 23 May 2017 в 12:29
поделиться