5

Antes me tiro a mi equipo en la próxima semana ...NHibernate.AssertionFailure: identificador nulo

he comprobado todos los demás consulta sobre este, pero ninguno de ellos tiene la solución. Deshizo este código, pero todavía no funciona.

estoy consiguiendo este error al guardar un objeto: NHibernate.AssertionFailure: identificador nulo

Este es mi archivo de asignación:

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

Ésta es la entidad:

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

Este es mi código de prueba:

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

Y luego golpear ... Rompe con

[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 

si alguien está interesado, así es como se construye la fábrica de sesión:

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

¿Se puede publicar el script de creación para la tabla de pedidos? – twaggs

+0

Actualmente solo hay una tabla con el campo en, incremento automático, int, no anulable – Paul

+0

(creo que he sido un poco pillock ........) – Paul

Respuesta

1

Necesitas o bien asignar su entitity un id al intentar para crear uno nuevo o especificar cómo se genera en el archivo de mapeo. Cambiar su asignación a:

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

Creo que "Identidad" es el valor predeterminado para ese valor ... desafortunadamente eso no funcionó – Paul

+0

@Paul - eliminar 'protected' del conjunto en la propiedad orderid – Justin

15

El valor predeterminado es nativo el cual será a su vez en uso Identidad de SQL Server 2008. Mi apuesta es que usted no tiene identidad especificada en la columna en la definición de la tabla.

+3

Esa es la explicación correcta. Alguien debería aceptar esto como la respuesta. – Tobias

2

Compruebe que su tabla no tenga un disparador que esté interfiriendo con INSERT, o tal vez llamando a un procedimiento almacenado en la inserción.

Cuando NHibernate inserta la entidad, solicitará a la base de datos la clave primaria autogenerada de la nueva entidad.

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

Nota del seleccione SCOPE_IDENTITY() llamada.

Si SCOPE_IDENTITY devuelve NULL, obtendrá la excepción NHibernate.AssertionFailure: null identifier.

Como ejemplo, un activador "INSTEAD OF INSERT" hará que SCOPE_IDENTITY devuelva nulo y active la aserción NHibernate.

Si encuentra un disparador que interfiere, puede solucionar si es el problema real deshabilitándolo temporalmente. A largo plazo, puede decidir si eliminar el activador por completo si ya no es necesario.

Como alternativa, puede envolver su inserción en una transacción; luego deshabilite el disparador antes de la inserción, haga la operación de guardar/insertar real de la entidad, luego vuelva a habilitar el activador y confirme la transacción.

+1

¡Puede ser útil incluso cuando no está en la oficina David! – Dmihawk