NHibernate.AssertionFailure:null标识符
在我将计算机推入下周之前……
我已经检查了所有关于此问题的其他问题,但他们都没有解决方案。 我已经剥离了这个代码,但它仍然没有工作。
保存对象时出现此错误:NHibernate.AssertionFailure:null标识符
这是我的映射文件:
public class OrderMap : BaseMap { 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();
默认生成器是Native,它将依次使用Identity for SQL Server 2008.我敢打赌,您没有在表定义中的列上指定标识。
检查您的表是否没有干扰INSERT的触发器,或者可能在插入时调用存储过程。
当NHibernate插入实体时,它会向数据库询问新实体的自动生成的主键。
INSERT INTO [Order] (MyProperty) VALUES (@p0); select SCOPE_IDENTITY()
请注意选择SCOPE_IDENTITY()调用。
如果SCOPE_IDENTITY返回NULL,那么您将获得NHibernate.AssertionFailure:null标识符exception。
例如,“INSTEAD OF INSERT”触发器将使SCOPE_IDENTITY返回null,并触发NHibernate断言。
如果发现触发器发生干扰,可以通过暂时禁用它来解决是否存在实际问题。 从长远来看,如果不再需要触发器,您可以决定是否完全摆脱触发器。
或者,您可以将插入包装在事务中; 然后在插入之前禁用触发器,执行实体的实际保存/插入,然后重新启用触发器并提交事务。
您需要在尝试创建新权限时为您的权利分配id,或者在映射文件中指定它的生成方式。 将映射更改为:
Id(x => x.Id).Column("OrderId").GeneratedBy.Identity();