Поведение NHibernate Cascade для обновлений сессий - PullRequest
1 голос
/ 12 августа 2011

Документация по настройкам каскада NHibernate, обсуждает настройки в контексте вызова методов Save () Update () и Delete ().Но я не могу найти обсуждения каскадного поведения в контексте неявного обновления, которое происходит, когда кто-либо загружает, модифицирует и сохраняет объекты в одном сеансе.В этом случае явный вызов для обновления не требуется, так что происходит с настройками каскада?

Это может показаться глупым вопросом, но причина, по которой я поднимаю этот вопрос, заключается в том, что я пытаюсь выяснить, как NHibernate поддерживает концепцию совокупных границ в контексте доменного дизайна.Позвольте мне привести пример, который проиллюстрирует, что я пытаюсь получить.

Предположим, у меня есть приложение канонического счета с сущностями Invoice, Buyer и LineItem.Счет-фактура является агрегированным корнем, а LineItem находится в том же агрегированном состоянии, но Покупатель является собственным агрегированным корнем.

Я хочу смоделировать это в NHibernate, настроив мое сопоставление таким образом, чтобы каскад из счета-фактуры в LineItem был All-DeleteOrphans, а для счета-фактуры - покупателю None.

На основеДокументацию, которую я прочитал, используя мои желаемые настройки каскада, если я работаю с отключенными объектами и делаю следующее, сохраняются только Invoice и LineItems:

disconnectedInvoice.ShippedDate = DateTime.Today();
disconnectedInvoice.LineItems[2].Backordered = true;
disconnectedInvoice.Buyer.Address = buyersNewAddress;

session.Update(disconnectedInvoice);
session.Flush();

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

var invoice = session.Get<Invoice>(invoiceNumber);
invoice.ShippedDate = DateTime.Today();
invoice.LineItems[2].Backordered = true;
invoice.Buyer.Address = buyersNewAddress;
session.Flush();

В документации NHibernate говорится, что flush сохраняет изменения для грязных объектов, связанных с сеансом.Исходя из этого, можно предположить, что обновления счета-фактуры, Покупателя и LineItems будут сохраняться.

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

Я допускаю, что этот пример представляет плохой DDD.Если Покупатель не является частью совокупности, он не должен обновляться в данный момент.Или, по крайней мере, его не следует обновлять через совокупность счетов-фактур.Однако, за исключением DDD, вопрос, который меня на самом деле больше интересует, заключается в определении того, соблюдаются ли правила каскада для обновлений в сценарии того же сеанса, так же, как и в отключенном сценарии.

1 Ответ

1 голос
/ 13 августа 2011

В документации NHibernate говорится, что при сбросе сохраняются изменения для грязных объектов, связанных с сеансом.

Основной проблемой является различие между отключенными и подключенными объектами.Каскадирование ведет себя одинаково для обоих, но неявные обновления различны.Для сущностей, загруженных сеансом, нет необходимости каскадировать сохранение для покупателя, поскольку оно будет избыточным.Для отсоединенного объекта вам необходим каскад, поскольку не будет никаких неявных обновлений для этого Покупателя, поскольку он никогда не был явно включен в сеанс.

...