NHibernate.AssertionFailure:空标识符
本文关键字:标识符 AssertionFailure NHibernate | 更新日期: 2023-09-27 18:14:57
在我把我的电脑踢到下周之前…
我已经检查了关于这个的所有其他问题,但没有一个有解决方案。我已经把这段代码剥离回来了,但它仍然不能工作。
我得到这个错误时,保存一个对象:NHibernate。AssertionFailure: null identifier
这是我的映射文件: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();
默认的生成器是Native,它将在SQL Server 2008中使用Identity。我敢打赌,您没有在表定义中的列上指定标识。
检查表中没有干扰INSERT操作的触发器,或者在INSERT操作时调用存储过程。
当NHibernate插入实体时,它会向数据库询问新实体的自动生成的主键。
INSERT INTO [Order] (MyProperty) VALUES (@p0); select SCOPE_IDENTITY()
注意select SCOPE_IDENTITY()调用
如果SCOPE_IDENTITY返回NULL,那么你将得到NHibernate。AssertionFailure: null identifier exception.
作为一个例子,一个"INSTEAD OF INSERT"触发器将使SCOPE_IDENTITY返回null,并触发NHibernate断言。
如果您发现一个触发器干扰,您可以通过暂时禁用它来排除是否是实际问题。从长远来看,如果不再需要,你可以决定是否完全取消触发器。
或者,您可以将insert封装在事务中;然后在插入之前禁用触发器,执行实体的实际保存/插入,然后重新启用触发器并提交事务。
在尝试创建一个新的实体时,您需要为您的实体分配一个id,或者指定如何在映射文件中生成它。将映射更改为:
Id(x => x.Id).Column("OrderId").GeneratedBy.Identity();