NHibernate.AssertionFailure: null identifier

半腔热情 提交于 2019-12-13 13:15:13

问题


Before I kick my computer in to next week...

I've checked out every other question about this, but none of them have the solution. I've stripped this code right back, but it's still not working.

I'm getting this error when saving an object: NHibernate.AssertionFailure: null identifier

This is my mapping file:

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

This is the entity:

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

This is my test code:

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

And then bang...it breaks with

[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

if anyone's interested, this is how the session factory is built:

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();

回答1:


The default generator is Native which will in turn use Identity for SQL Server 2008. My bet is that you don't have identity specified on the column in the table definition.




回答2:


Check that your table doesn't have a trigger that is interfering with the INSERT, or perhaps calling a stored procedure on insert.

When NHibernate inserts the entity, it will ask the database for the auto-generated primary key of the new entity.

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

Note the select SCOPE_IDENTITY() call.

If SCOPE_IDENTITY returns NULL, then you'll get the NHibernate.AssertionFailure: null identifier exception.

As an example, an "INSTEAD OF INSERT" trigger will make SCOPE_IDENTITY return null, and trigger the NHibernate assertion.

If you find a trigger interfering, you can troubleshoot whether it is the actual problem by temporarily disabling it. For the long term, you can then decide whether to get rid of the trigger entirely if it's no longer needed.

Alternatively, you can wrap your insert in a transaction; then disable the trigger before the insert, do the actual save/insert of the entity, then re-enable the trigger and commit the transaction.




回答3:


You need to either assign your entitity an id when trying to create a new one or specify how it is generated in the mapping file. Change your mapping to:

Id(x => x.Id).Column("OrderId").GeneratedBy.Identity();


来源:https://stackoverflow.com/questions/8138370/nhibernate-assertionfailure-null-identifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!