Руководство по применению NHibernate Definitive Cascade - PullRequest
25 голосов
/ 13 января 2010

Существуют ли интернет-ресурсы, в которых есть исчерпывающее руководство по всем настройкам каскада для NHibernate, которое будет включать примеры структуры классов, HBM и последствия действий с каждым из параметров каскада для всех отношений с NH.

Также было бы полезно, если бы были примеры, когда общие ассоциации выполняются наиболее правильным образом, например, для настройки таблицы состояний, в которой вы никогда не будете каскадно удалять состояние, или для удаления объекта, имеющего CreatedBy. Свойство пользователя никогда не приведет к удалению пользователя каскадом и т. Д.

Ответы [ 3 ]

57 голосов
/ 11 февраля 2010

Следующее адаптировано из справочника Java Hibernate http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/objectstate.html#objectstate-transitive для NHiberate 3.0 (т. Е. Текущей магистрали svn).

Для каждой базовой операции сеанса NHibernate - включая Persist (), Merge (), SaveOrUpdate (), Delete (), Lock (), Refresh (), Evict (), Replicate () - существует соответствующий каскад стиль. Соответственно, каскадные стили называются постоянными, объединяются, сохраняются-обновляются, удаляются, блокируются, обновляются, выселяются, реплицируются. Каскадным стилем для Save () и Update () является save-update; для SaveAndUpdateCopy () это слияние; и для PersistOnFlush () это сохраняется. И удалить это псевдоним для удаления.

Если вы хотите, чтобы операция связывалась вдоль ассоциации, вы должны указать это в документе сопоставления. Например:

<one-to-one name="person" cascade="persist"/>

Каскадные стили могут быть объединены:

<one-to-one name="person" cascade="persist,delete,lock"/>

Вы можете использовать cascade = "all", чтобы указать, что все операции должны каскадироваться вдоль ассоциации. По умолчанию cascade = "none" указывает, что никакие операции не должны каскадироваться.

Специальный каскадный стиль delete-orphan применяется только к ассоциациям «один ко многим» и указывает, что операция Delete () должна применяться к любому дочернему объекту, который удаляется из ассоциации. И all-delete-orphan это то же самое, что и all-delete-orphan.

Рекомендации:

  • Обычно не имеет смысла включать каскад для ассоциации <многие-к-одному> или <многие-ко-многим>. Каскад часто полезен для ассоциаций <один-к-одному> и <один-ко-многим>.
  • Если срок жизни дочернего объекта ограничен сроком жизни родительского объекта, сделайте его объектом жизненного цикла, указав cascade = "all-delete-orphan".
  • В противном случае вам может вообще не понадобиться каскад. Но если вы думаете, что вы часто будете работать с родителем и потомками вместе в одной транзакции и хотите сэкономить немного времени на наборе текста, подумайте об использовании cascade = "persist, merge, save-update".

Отображение ассоциации (либо однозначной ассоциации, либо коллекции) с помощью cascade = "all" помечает ассоциацию как родительский / дочерний стиль, где сохранение / обновление / удаление родительского объекта приводит к сохранению / обновлению / удалению ребенок или дети. Дочерний объект, на который родительский объект не ссылается, не удаляется автоматически, за исключением случая, когда сопоставление <один ко многим> сопоставлено с помощью cascade = "delete-orphan". Точная семантика каскадных операций для родительских / дочерних отношений следующая:

  • Если родительский элемент передается в Persist (), все дочерние элементы передаются в Persist ()
  • Если родительский элемент передается в Merge (), все дочерние элементы передаются в Merge ()
  • Если родительский элемент передается в Save (), Update () или SaveOrUpdate (), все дочерние элементы передаются в SaveOrUpdate ()
  • Если постоянный родитель ссылается на временного или отсоединенного потомка, он передается в SaveOrUpdate ()
  • Если родитель удален, все дочерние элементы передаются в Delete ()
  • Если постоянный родитель разыменовывает дочерний объект, ничего особенного не происходит - приложение должно явно удалить дочерний элемент, если это необходимо - если только cascade = "delete-orphan", в этом случае дочерний элемент-сирота будет удален.
3 голосов
/ 09 февраля 2010

Я не знаю какого-либо «окончательного» руководства, но лучший ресурс, который я знаю, - это пост в блоге Айенде, который является одним из окончательных гуру в NHibernate:

NHibernate Cascades: различие между всеми, all-delete-orphans и save-update

Для меня я на самом деле использую только cascade="none" и cascade="all". all-delete-orphan иногда это вариант. Все остальное подозрительно. Например, почему я должен неявно создавать экземпляр, потому что на него ссылаются, когда он живет дольше, чем содержащий объект? Для меня есть только две ситуации: либо объект является зависимым, либо независимым.

3 голосов
/ 07 февраля 2010

Это может быть очевидный совет, но я бы посоветовал просмотреть старое сообщение, сделанное Ayende . Быстрый поиск NHibernate и каскада на его сайте выявил несколько интересных постов. Однако они могут быть слишком скудными для ваших нужд.

Хотя это и не интернет-ресурс как таковой, я бы также порекомендовал NHibernate в действии . В главах 3, 4 и 6 подробно рассматриваются каскады. Книга ориентирована на NHibernate 1.2. Однако я верю, что выйдет новая редакция книги, ориентированная на выпуск NHibernate 3.0; возможно, стоит присмотреть.

Как бы мне ни хотелось увидеть полное руководство по каскадам, я его не видел. Возможно, вы могли бы обобщить некоторые посты в блоге, обсуждающие каскады, с вашим собственным постом в своем блоге.

...