我在使用NHibernate(和Fluent NHibernate)时遇到问题,并且当Version属性在抽象基类上时尝试使用session.Lock功能。
我已经能够将示例简化为以下域模型:
public abstract class AbstractBaseClass : Entity
{
public virtual int Version { get; protected set; }
public virtual string Name { get; set; }
}
public class ChildOne : AbstractBaseClass
{
public virtual string Address { get; set; }
}
我的流利配置是:
fluentConfiguration.Mappings(map => map.AutoMappings.Add(
AutoMap.AssemblyOf<AbstractBaseClass>()
.Where(x => x.IsSubclassOf(typeof(Entity)))
.IncludeBase<AbstractBaseClass>()
.Conventions.Add(DefaultCascade.All())));
当我尝试在会话上使用Lock方法时,数据库提供程序抛出异常:
NHibernate.Exceptions.GenericADOException:无法检索 version:[NHLockTest.ChildOne#1] [SQL:SELECT Version FROM “AbstractBaseClass”WHERE Id =?] ----&gt; System.Data.SQLite.SQLiteException:SQLite错误没有这样的列: AbstractBaseClass_id
以下是我用于在一个简单示例中重新创建问题的单元测试:
[Test]
public void Should_Lock_Entity()
{
using (var session = _sessionFactory.OpenSession())
{
var entity = new ChildOne {Address = "Some Address", Name = "Some Name"};
session.Save(entity);
session.Flush();
}
using (var session = _sessionFactory.OpenSession())
{
var entity = session.Query<ChildOne>().Single();
//this is where the exception is raised
session.Lock(entity, LockMode.Force);
}
}
当我配置NHibernate来显示SQL时,我看到在调用session.Lock时正在生成以下语句:
UPDATE "AbstractBaseClass"
SET Version = @p0
WHERE AbstractBaseClass_id = @p1 AND Version = @p2;
@p0 = 2 [Type: Int32 (0)], @p1 = 1 [Type: Int64 (0)], @p2 = 1 [Type: Int32 (0)]
它似乎正在尝试更新基类的表,而是使用子表中的forign键列名而不是基类表上的Id列。这显然与上述异常消息的含义无关。
我在这里做错了什么或者我在NHibernate中发现了一个错误?
答案 0 :(得分:0)
在非流畅的NHibernate中,您必须在XML映射中设置:polymorphism =“explicit”。
似乎不适用于流利的nhibernate的旧版本:
fluent nhibernate convention : setting polymorphism mode
你可以试试(我还没有测试过):
fluentConfiguration.Mappings(map => map.AutoMappings.Add(
AutoMap.AssemblyOf<AbstractBaseClass>()
.Where(x => x.IsSubclassOf(typeof(Entity)))
.IncludeBase<AbstractBaseClass>()
.Polymorphism.Explicit()
.Conventions.Add(DefaultCascade.All())));