NHibernate.AssertionFailure: нулевой идентификатор

Прежде чем я перейду на следующую неделю ...

Я проверил все вопросы по этому поводу, но ни у одного из них нет решения. Я удалил этот код обратно, но он все еще не работает.

Я получаю эту ошибку при сохранении объекта: NHibernate.AssertionFailure: нулевой идентификатор

Это мой файл сопоставления:

public class OrderMap : BaseMap<Order>
{
    public SalesOrderMap()
    {
        Id(x => x.Id).Column("OrderId");
    }
}

Это сущность:

public class Order
{
    public virtual int Id { get; protected set; }
}

Это мой тестовый код:

Order order = new Order();
ISession session = SessionFactory.GetCurrentSession();
session.SaveOrUpdate(order); <----EXCEPTION ON THIS LINE
session.Flush();

А потом бац ... рвется с

[AssertionFailure: null identifier]
  NHibernate.Engine.EntityKey..ctor(Object identifier, String rootEntityName, String entityName, IType identifierType, Boolean batchLoadable, ISessionFactoryImplementor factory, EntityMode entityMode) +135
   NHibernate.Engine.EntityKey..ctor(Object id, IEntityPersister persister, EntityMode entityMode) +70
   NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +545
   NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +322
   NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) +130
   NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) +27
   NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) +63
   NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) +89
   NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) +188
   NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) +259
   NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj) +256

Если кому-то интересно, вот как строится фабрика сессий:

ControllerSource.SessionFactory = Fluently.Configure()
                .Database(MsSqlConfiguration.MsSql2008.ConnectionString(DataConfig.ConnectionString))
                .Mappings(x => x.FluentMappings.Add(typeof (OrderMap)))
                .ExposeConfiguration(c =>{
                                             c.SetProperty("generate_statistics", "false");
                                             c.SetProperty("current_session_context_class", contextClass);
                                             c.SetProperty("cache.use_second_level_cache", "false");
                                             c.SetProperty("cache.use_query_cache", "false");
                                             c.SetProperty("connection.release_mode", "on_close");
                })
                .BuildSessionFactory();

person Paul    schedule 15.11.2011    source источник
comment
Можете ли вы опубликовать скрипт создания таблицы заказов?   -  person twaggs    schedule 15.11.2011
comment
В настоящее время это просто таблица с полем, автоматическим увеличением, int, не допускающим значения NULL   -  person Paul    schedule 15.11.2011
comment
(Думаю, я был немного не в себе ........)   -  person Paul    schedule 15.11.2011
comment
Как насчет отображения вашего SessionFactory.GetCurrentSession   -  person twaggs    schedule 15.11.2011
comment
В моем похожем случае этот пост был полезен [AssertionFailure: «нулевой идентификатор» - FluentNH + SQLServerCE] [1] [1]: stackoverflow.com/questions/2361730/   -  person xyz    schedule 28.01.2012


Ответы (3)


Генератором по умолчанию является Native, который, в свою очередь, будет использовать Identity для SQL Server 2008. Могу поспорить, что у вас нет идентификатора, указанного в столбце в определении таблицы.

person Jamie Ide    schedule 15.11.2011
comment
Это правильное объяснение. Кто-то должен принять это как ответ. - person Tobias; 21.12.2011

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

Когда NHibernate вставляет объект, он запрашивает у базы данных автоматически сгенерированный первичный ключ нового объекта.

INSERT INTO [Order] (MyProperty) VALUES (@p0); select SCOPE_IDENTITY()

Обратите внимание на вызов select SCOPE_IDENTITY ().

Если SCOPE_IDENTITY возвращает NULL, вы получите исключение NHibernate.AssertionFailure: нулевой идентификатор.

Например, триггер «INSTEAD OF INSERT» заставит SCOPE_IDENTITY вернуть значение null и вызвать утверждение NHibernate.

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

В качестве альтернативы вы можете заключить свою вставку в транзакцию; затем отключите триггер перед вставкой, выполните фактическое сохранение / вставку объекта, затем снова включите триггер и зафиксируйте транзакцию.

person David Moore    schedule 24.02.2015
comment
Вы можете быть полезны, даже если вы не в офисе Дэвид! - person Dmihawk; 11.05.2017

Вам нужно либо присвоить вашей сущности идентификатор при попытке создать новый, либо указать, как он создается в файле сопоставления. Измените свое сопоставление на:

Id(x => x.Id).Column("OrderId").GeneratedBy.Identity();
person Justin    schedule 15.11.2011
comment
Я считаю, что Identity является значением по умолчанию для этого значения ... к сожалению, это не сработало - person Paul; 15.11.2011
comment
@Paul - удалить 'protected' из набора в свойстве orderid - person Justin; 15.11.2011