Проблема NHibernate с Session.Lock и абстрактный базовый класс со свойством Version - PullRequest
1 голос
/ 21 февраля 2012

У меня проблемы с использованием NHibernate (и Fluent NHibernate) и попыткой использовать функцию session.Lock, когда свойство Version находится в абстрактном базовом классе.

Мне удалось упростить пример внизв следующую модель домена:

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: не удалось получить версию: [NHLockTest.ChildOne # 1] [SQL: ВЫБЕРИТЕ версию ИЗ "AbstractBaseClass", ГДЕ Id =?] ----> 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)]

Кажется, пытается обновить таблицу длябазовый класс, но вместо этого использует имя столбца внешнего ключа из дочерней таблицы, а не столбец Id в таблице базового класса.Это явно не связано с тем, что говорится в сообщении об исключении, приведенном выше.

Я что-то здесь не так делаю или обнаружил ошибку в NHibernate?

1 Ответ

0 голосов
/ 21 февраля 2012

В не беглом NHibernate вы должны установить: polymorphism = "явный" в вашем отображении XML.

Кажется, что не работает в более старых версиях Fluent Nhibernate:

соглашение Fluent Nhibernate: установка режима полиморфизма

Вы можете попробовать что-то вроде (Iеще не проверял):

fluentConfiguration.Mappings(map => map.AutoMappings.Add(
            AutoMap.AssemblyOf<AbstractBaseClass>()
                .Where(x => x.IsSubclassOf(typeof(Entity)))
                .IncludeBase<AbstractBaseClass>()
                .Polymorphism.Explicit()
                .Conventions.Add(DefaultCascade.All())));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...