5

Trước khi tôi bắt máy tính của tôi trong tuần tiếp theo ...NHibernate.AssertionFailure: null nhận dạng

Tôi đã kiểm tra ra mọi câu hỏi khác về vấn đề này, nhưng không ai trong số họ có giải pháp. Tôi đã xóa mã này ngay lập tức, nhưng nó vẫn không hoạt động.

Tôi nhận được lỗi này khi lưu một đối tượng: NHibernate.AssertionFailure: null nhận dạng

này được tập tin bản đồ của tôi:

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

Đây là thực thể:

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

Đây là mã thử nghiệm của tôi:

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

Và rồi đập mạnh ... nó phá vỡ với

[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 

nếu có ai quan tâm, đây là cách các nhà máy được xây dựng phiê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

Bạn có thể đăng tập lệnh tạo cho bảng thứ tự không? – twaggs

+0

Hiện tại chỉ là một bảng có trường, tự động gia tăng, int, không thể rỗng – Paul

+0

(Tôi nghĩ mình đã từng là một viên thuốc ........) – Paul

Trả lời

1

Bạn cần phải hoặc gán entitity bạn một id khi cố gắng để tạo một cái mới hoặc chỉ định cách nó được tạo ra trong tệp ánh xạ. Thay đổi ánh xạ của bạn thành:

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

Tôi tin rằng "Danh tính" là giá trị mặc định cho giá trị đó ... không may là không hoạt động – Paul

+0

@Paul - xóa 'được bảo vệ' khỏi tập hợp trong thuộc tính orderid – Justin

15

Máy phát mặc định là Native sẽ sử dụng nhận dạng cho SQL Server 2008. Đặt cược của tôi là bạn không có nhận dạng được xác định trên cột trong định nghĩa bảng.

+3

Đó là giải thích đúng. Ai đó nên chấp nhận điều này như là câu trả lời. – Tobias

2

Kiểm tra xem bảng của bạn không có trình kích hoạt can thiệp vào INSERT hay có thể gọi thủ tục được lưu trữ khi chèn.

Khi NHibernate chèn thực thể, nó sẽ yêu cầu cơ sở dữ liệu cho khóa chính được tạo tự động của thực thể mới.

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

Lưu ý chọn SCOPE_IDENTITY() gọi.

Nếu SCOPE_IDENTITY trả về NULL, thì bạn sẽ nhận được NHibernate.AssertionFailure: null định danh ngoại lệ.

Ví dụ, kích hoạt "INSTEAD OF INSERT" sẽ làm cho SCOPE_IDENTITY trả về null và kích hoạt xác nhận NHibernate.

Nếu bạn tìm thấy trình kích hoạt can thiệp, bạn có thể khắc phục sự cố đó có phải là sự cố thực tế hay không bằng cách tạm thời vô hiệu hóa nó. Về lâu dài, bạn có thể quyết định loại bỏ hoàn toàn trình kích hoạt nếu nó không còn cần thiết nữa.

Cách khác, bạn có thể bọc phần chèn vào trong giao dịch; sau đó vô hiệu hóa trình kích hoạt trước khi chèn, thực hiện lưu/chèn thực tế của thực thể, sau đó kích hoạt lại trình kích hoạt và thực hiện giao dịch.

+1

Bạn có thể hữu ích ngay cả khi bạn không ở trong văn phòng David! – Dmihawk