NHibernate: "сбор не обрабатывался flush()", вызванный проблемой ленивой загрузки

У меня есть два класса:

class Parent
{
    public virtual Child Child { get; set; }
}

class Child 
{
    public virtual IList<GrandChild> GrandChildren { get; set; }
}

У меня есть экземпляр Parent, загруженный из моего ISession, Parent.Child, который ленивый загружен (НЕ загружен в этот момент). Child.GrandChildren также лениво загружен.

Если я это сделаю:

session.Save(new Parent { Child = existingParent.Child } );

Я получаю collection [Child.GrandChildren] was not processed by flush()

Если я вызываю свойство existingParent Child для загрузки, просто обратившись к нему:

var x = existingParent.Child.Name

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

** Изменить: ** Родитель имеет FK для ребенка

Я использую NH 2.1.2.4000

Спасибо

Ответ 1

У меня была аналогичная проблема, комментарий от @Jamie Ide помог мне понять, в чем проблема. Я инициализировал коллекцию внутри конструктора, что заставило NHibernate думать, что коллекция была грязной, даже если не требовалось сохранять этот конкретный объект в этот момент.

Исключением я получил: ClassName: ОШИБКА | NHibernate.AssertionFailure: коллекция [CollectionName] не обрабатывалась flush()

Я все еще хочу сделать эту инициализацию, но я думаю, мне нужно найти другое решение этой проблемы.

Ответ 2

Что такое каскадная настройка для каскадных изменений от Child до коллекции GrandChildren? Я думаю, что NHibernate выбрасывает это исключение, если коллекция грязная, но настройка каскада не приводит к тому, что изменения сохраняются.

Ответ 3

Вы можете использовать session.Load для ссылки на существующий экземпляр Child, не совершая поездки в db. Это должно сделать это, я думаю:

session.Save(new Parent { Child = session.Load(existingParent.Child.Id) } );

Но убедитесь, что вызов .Id не вызывает отключение db.