Как сохранить ребенка с присвоенным идентификатором в nhibernate

Очень простое решение: заменить https: // на git: //

Использовать git: //the.repository вместо https: //the.repository и будет работать.

У меня была эта проблема в Windows с TortoiseGit, и это решило ее.

20
задан Serhat Ozgel 1 July 2009 в 17:30
поделиться

3 ответа

При каскадном переходе от родителя к потомку NHibernate использует метод SaveOrUpdate. Вы правы, что NHibernate нужно каким-то образом определить, следует ли выполнять вставку или обновление. Он будет искать несохраненное значение в трех разных полях, чтобы определить, является ли объект новым.

  1. Идентификатор
  2. Версия
  3. Отметка времени

С назначенным идентификатором вам понадобится поле Версия или Отметка времени, чтобы указать, что объект новый.

Альтернативой может быть вызов Сохранить ( ) на детей явно.

28
ответ дан 29 November 2019 в 23:45
поделиться

Я не на 100% уверен, что это та же проблема, что и у вас, но моей базе данных назначен идентификатор на 100% (тьфу), и мне пришлось создать перехватчик, который отслеживал, дочерний элемент сохраняется или не сохраняется для работы каскадов.

Код вырезан / вставлен (поэтому у него тупые имена ... Сначала я не понял на 100%!), и я изначально получил 90 % из онлайн-документации (которую я не могу найти через google прямо сейчас ... извините):

Базовый класс, который вы помещаете в объект, которому назначен идентификатор, который вы хотите каскадировать:

public class Persistent
{
    private bool _saved = false;

    public virtual void OnSave()
    {
        _saved = true;
    }

    public virtual void OnLoad()
    {
        _saved = true;
    }

    public virtual bool IsSaved
    {
        get { return _saved; }
    }
}

Перехватчик, который вы добавляете в session:

public class TrackingNumberInterceptor : EmptyInterceptor
{
    public override bool? IsTransient(object entity)
    {
        if (entity is Persistent)
        {
            return !((Persistent)entity).IsSaved;
        }
        else
        {
            return null;
        }
    }

    public override bool OnLoad(object entity, object id, object[] state, string[] propertyNames, IType[] types)
    {
        if (entity is Persistent) ((Persistent)entity).OnLoad();
        return false;
    }

    public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
    {
        if (entity is Persistent) ((Persistent)entity).OnSave();
        return false;
    }
}

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

По умолчанию объект начинается с persisted (_saved) в false. Когда объект либо загружается, либо сохраняется NHibernate, триггер устанавливает для флага сохраняемых объектов (_saved) значение true.

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

15
ответ дан 29 November 2019 в 23:45
поделиться

Вызов session.SaveOrUpdate( childObject ) должен решить проблему.

-1
ответ дан 29 November 2019 в 23:45
поделиться
Другие вопросы по тегам:

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