Руководство по применению NHibernate Definitive Cascade

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

25
задан Chris Marisic 13 January 2010 в 16:35
поделиться

3 ответа

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

Для каждой базовой операции сессии NHibernate - включая Persist(), Merge(), SaveOrUpdate(), Delete(), Lock(), Refresh(), Evict(), Replicate() - существует соответствующий каскадный стиль. Соответственно, каскадные стили называются persist, merge, save-update, delete, lock, refresh, evict, replicate. Каскадным стилем для Save() и Update() является save-update, для SaveAndUpdateCopy() - merge, а для PersistOnFlush() - persist. А remove - это псевдоним для delete.

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

<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", в этом случае "осиротевший" ребенок удаляется.
57
ответ дан 28 November 2019 в 18:21
поделиться

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

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

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

3
ответ дан 28 November 2019 в 18:21
поделиться

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

NHibernate Cascades: разница между all, all-delete-orphans и save-update

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

3
ответ дан 28 November 2019 в 18:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: