Nhibernate HiLo生成器正在生成重复的ID

时间:2016-02-22 21:20:45

标签: c# sqlite nhibernate

我正面临着nHibernate的奇怪行为。在某些情况下,它会使用hi-lo生成器生成重复的ID。 如果事务被回滚,并且要生成的id的数量超过hi-lo max,最终它会开始生成重复项 - Debug.Assert失败。

也许某人遇到过类似的事情,或者只知道如何防止这种情况发生?如果重要,数据库就是sqlite。

private void Test(ISessionFactory factory)
    {
        for (int i = 0; i < 3; i++)
        {
            using (var session = factory.OpenSession())
            using (var transaction = session.BeginTransaction())
            {
                CheckIdGenerator(session.GetSessionImplementation(), 11);
                transaction.Rollback();
            }
        }
    }

private void CheckIdGenerator(ISessionImplementor sessionImplementor, int max)
{
    var factory = sessionImplementor.Factory;
    var mapping= (SingleTableEntityPersister)factory.GetClassMetadata(typeof(Dummy));
    var generator= mapping.IdentifierGenerator;

    var ids = new List<long>();
    for (int i = 0; i < max; i++)
    {
        var id = (long)generator.Generate(sessionImplementor, null);
        Debug.Assert(!ids.Contains(id));
        ids.Add(id);
    }
}

映射:

class DummyMap : ClassMap<Dummy>
      {
            public DummyMap()
            {
                Id(x => x.Id)
                    .UniqueKey(nameof(Dummy.Id))
                    .GeneratedBy.HiLo("NHHiLoIdentity", "NextHiValue", "10",
                        $"[EntityName] = '[{nameof(Dummy)}]'")
                    .Not.Nullable();
            }
        }

1 个答案:

答案 0 :(得分:0)

NHibernate尝试在不同的事务中获取id,而Sqlite只允许一个已经有事务的连接。此事务将回滚,因此读取之间的hi值将相同。