代码之家  ›  专栏  ›  技术社区  ›  Tomas

Fluent NHibernate到内存中的SQLite DB在insert with Version时抛出异常

  •  1
  • Tomas  · 技术社区  · 14 年前

    我有一个相当大的域模型,它一直使用fluenthibernate到mssqlserver2008。

    最近我们遇到了并发问题,所以我实现了对NHibernate优秀版本的版本控制,目的是使用MSSQL timestamp 数据类型。我所有的实体都是 DomainEntity IAutoMappingOverride :

    public class DomainEntityOverride : IAutoMappingOverride<DomainEntity> {
        public void Override(AutoMapping<DomainEntity> mapping) {
            mapping.OptimisticLock.Version();
            mapping.Version(entity => entity.Version);
        }
    }
    

    此外,我使用 IVersionConvention :

    public class VersionConvention : IVersionConvention {
        public void Apply(IVersionInstance instance) {
            instance.Column("Version");
            instance.Generated.Always();
            instance.UnsavedValue("null");
            instance.Not.Nullable();
            instance.CustomSqlType("timestamp");
        }
    }
    

    我的理解是,这将导致总是生成版本,并检查并发问题。在我的开发和生产环境(都使用MSSQL2008)中,它似乎可以工作,但我使用SQLite的内存测试不再工作。

        [Test(Description = "Can save an aircraft and it is persisted")]
        public void PersistAircraft_NewAircraft_AircraftIsPersisted() {
            var id = saveEntity(_aircraft); //exception thrown here
    
            var persisted = getEntity<Aircraft>(id);
    
            Assert.That(persisted.Registration, Is.EqualTo(_aircraftRegistration));
            Assert.That(persisted.Remarks, Is.EqualTo(_aircraftRemark));
        }
    

    我得到了以下例外:

    Test 'NOIS.Persistence.Tests.InMemory.AircraftPersistenceTest.PersistAircraft_NewAircraft_AircraftIsPersisted' failed: NHibernate.Exceptions.GenericADOException : could not insert: [NOIS.Model.Entities.AircraftType#9c2809ea-c0c5-4778-838b-9e2500a6d2ef][SQL: INSERT INTO "AircraftType" (ProducedBy, Active, Remarks, Name, Code, Category_id, Id) VALUES (?, ?, ?, ?, ?, ?, ?)]
    ----> System.Data.SQLite.SQLiteException : Abort due to constraint violation
    AircraftType.Version may not be NULL
    

    在NHibernate.Persister.Entity.AbstractEntityPersister.Insert(对象id,对象[]字段,布尔值[]notNull,Int32 j,SqlCommandInfo sql,对象obj,ISessionImplementor会话) 在NHibernate.Persister.Entity.AbstractEntityPersister.Insert(对象id,对象[]字段,对象obj,ISessionImplementor会话) 在NHibernate.Action.EntityInsertAction.Execute()上 位于NHibernate.Engine.ActionQueue.ExecuteActions(IList列表) 在NHibernate.Engine.ActionQueue.ExecuteActions() 在NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent事件) 在NHibernate.Transaction.adotransation.Commit() fluentlyconfiguredMemoryDatabaseTest.cs(49,0):位于noi.Persistence.Tests.fluentlyconfiguredMemoryDatabaseTest.saveEntity(域实体) InMemory\AircraftPersistenceTest.cs(33,0):在NOIS.Persistence.Tests.InMemory.AircraftPersistenceTest.persistenaircraft\newaircrafts\u AircraftIsPersisted() --SQLiteException异常 在System.Data.SQLite.SQLite3.Reset(SQLiteStatement stmt) 位于System.Data.SQLite.SQLiteDataReader.NextResult() 在System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand命令,命令行为) 在System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior行为) 在System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()上 在NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd) 在NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(预期)

    1 回复  |  直到 14 年前
        1
  •  2
  •   Stefan Steinegger    14 年前

    我不确定我是否完全明白你在这里做什么。

    但据我所知,您使用的是SQL Server特性,这个时间戳在Sqlite中不可用。所以在那里不起作用。

    你不需要这个SqlServer来让NH的乐观锁定机制工作。它实际上完全由NH管理,不需要数据库中的任何特殊内容。只需定义一个整数列和属性并将其映射为实体版本。其他的都是NH做的。我从来不用别的东西。