NHibernate исключение "нулевой идентификатор" после вставки объекта - PullRequest
5 голосов
/ 11 июня 2009

У меня проблемы с сохранением объекта в базу данных SQL Server 2005. Я использую NHibernate 2.0.0.3002 для моего уровня персистентности. Типичное отображение с целочисленным идентификатором:

<id name="Id" unsaved-value="0">
  <column name="Id"/>
  <generator class="identity" />
</id>

Для краткости я опустил все остальное. Приложение использует класс репозитория с универсальным методом сохранения следующим образом

public void Save(T toSave)
{
    Save(new T[] { toSave });
}

public void Save(IEnumerable<T> toSave)
{
    using (ISession session = SessionFactory.OpenSession())
    {
        foreach (T item in toSave)
        {
            session.SaveOrUpdate(item);
        }
        session.Flush();
    }
}

При вызове SaveOrUpdate в сеансе выдается исключение с сообщением «нулевой идентификатор». Когда я проверяю базу данных, строка вставляется со всеми правильными значениями, поэтому я думаю, что проблема в том, что NHibernate пытается установить свойство Id объекта со значением, возвращаемым @@ IDENTITY. Через SQL Profiler я вижу, что вызывается @@ IDENTITY, поэтому не понимаю, почему возникает исключение.

Кто-нибудь еще имел эту проблему?

Ответы [ 5 ]

8 голосов
/ 15 июня 2009

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

вроде так:

public void Save(IEnumerable<T> toSave)
{
    using (ISession session = SessionFactory.OpenSession())
    {
        ITransaction transaction = Session.BeginTransaction();

        foreach (T item in toSave)
        {
            session.SaveOrUpdate(item);
        }

        transaction.Commit();           
        session.Flush();
    }
}

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

Кроме того, вы можете уточнить, где происходит исключение? Похоже, вы сохраняете родителя, а потом выбрасывает дочерний элемент, потому что идентификатор родителя равен нулю? Или это на самом деле приводит к спасению родителя?

1 голос
/ 15 июня 2009

Может быть полезно настроить log4net, чтобы вы могли регистрировать и просматривать действия, которые выполняет NHibernate ...

Однажды у меня была проблема с NHibernate при использовании Access, и я смог ее решить, настроив ведение журнала так, чтобы я мог точно определить причину проблемы.

Сообщение об ошибке, которое я получил, отличалось от вашего, но this - это статья, в которой я описываю, как я решил мою проблему. Возможно, это может быть полезно для вас. :)

0 голосов
/ 04 января 2013

У меня также была эта ошибка, и решение было заключить в транзакцию, как упоминал Бен. Однако я не смог заставить работать ни код Бена, ни gilles27 - возможно, потому, что я новичок в дженериках и NHibernate. Я создал немного другую реализацию, которая работает (используя Fluent NHibernate v1.3):

        public static ISession LocalDbSession = null;

    public static void Save<T>(T toSave)
    {
        using (var transaction = LocalDbSession.BeginTransaction())
        {
            LocalDbSession.Save(toSave);
            transaction.Commit();
            LocalDbSession.Flush();
        }
    }

    public static void Save<T>(IEnumerable<T> toSave)
    {
        using (var transaction = LocalDbSession.BeginTransaction())
        {
            foreach (T item in toSave)
            {
                LocalDbSession.Save(item);
            }

            transaction.Commit();
            LocalDbSession.Flush();
        }
    }
0 голосов
/ 12 июня 2009

Идентичность довольно обескуражена разработчиками NHibernate .. главная проблема, с которой мы столкнулись, заключается в том, что до тех пор, пока вы не сбросите, вы не получите Id. В вашем Int случае HiLo будет хорошей заменой.

При этом я думаю, что вы действительно хотите это сделать ...

<id name="Id" column="Id" unsaved-value="0">
   <generator class="identity"/>  
</id>
0 голосов
/ 11 июня 2009

я думаю вместо генератора class = "identityitiy" />

попробуй генератор class = "guid.comp"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...