0

私は、モノリシックなレガシー データベースの上に NHibernate マッピングを持っています。本番環境にロールアウトして以来、NHibernate から散発的にエラーが発生し、1 日あたり約 60,000 件のイベントが処理されています。頻度は約 0.006% - 0.013% です)。

私と私の同僚が判断できる限り、これらの失敗したイベント/メッセージと成功したものに違いはありません。

私たちが得ているエラーは

NHibernate.AssertionFailure: null identifier
at NHibernate.Engine.EntityKey..ctor(Object identifier, String rootEntityName, String entityName, IType identifierType, Boolean batchLoadable, ISessionFactoryImplementor factory, EntityMode entityMode)
at NHibernate.Engine.EntityKey..ctor(Object id, IEntityPersister persister, EntityMode entityMode)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
at NHibernate.Impl.SessionImpl.Save(Object obj)

ただし、識別子列は、ネイティブ ジェネレーターを使用する値型 (System.Int32) です。どうすればnullにできますか?

public class MyItem {
   public int MyItemId { get; set; }
}

public class MyItemMap : ClassMapping<MyItem>
{
    public MyItemMap ()
    {
        Table("MyItemTable");

        Id(m => m.MyItemId, x =>
        {
            x.Column("MyItem_ID");
            x.Generator(Generators.Native);
            x.UnsavedValue(default(int));
        });
    }
}

だから、私の質問は本当にです。a) 識別子が値型 (つまり、null 不可) の場合に、NHibernate が null 識別子について文句を言うのはなぜですか? b) それについて私にできることはありますか?

4

1 に答える 1

0

問題を切り分けて再現することができました。

問題のテーブル (MyItemTable) には、IGNORE_DUP_KEY=ON のインデックスがありました。

また、別の問題により、ほぼ同一の行を 2 回挿入しようとしています。2 回目の挿入は警告で失敗し、実際には行は挿入されません。そのため、NHibernate が生成された ID を取得しようとすると、レコードが挿入されていないため、SQL Server はおそらく NULL を返します。

これがどのテストでも最初に表示されなかった理由は、データベースが最初からツールによってバージョン管理されていたのではなく、手動の移行によってバージョン管理されていたためです。また、データベース バージョニング ツールがレガシー データベースのスクリプトを作成したとき、インデックスは含まれていませんでした。そのため、統合テスト用に生成されたテスト環境/データベースにインデックスがありませんでした。モノリシックなレガシーの頭痛の種...

于 2013-12-06T06:00:30.130 に答える