NHibernate.Сумка пуста после создания в том же сеансе - PullRequest
1 голос
/ 03 октября 2011

У меня есть объект, который содержит список объектов.

public class Product: IProduct
{
    public virtual long     Id   { get; set; }
    public virtual string   Name { get; set; }

    public virtual IList<IFunction> Functions { get; set; }
}

public class Function : IFunction
{
    public virtual long     Id   { get; set; }
    public virtual string   Name { get; set; }

    public virtual IProduct Product { get; set; }
}

Отображаемый список объектов (IList ):

<bag name="Functions" cascade="all" table="T_WEBFUNCTIONS" lazy="false">
  <key column="PRODUCT_ID" />
  <one-to-many class="Function" />
</bag>

Код:

Я пытаюсь создать новый объект Product

    public IProduct SetProduct(string productName)
    {
         // Product repository, which have nhibernate opened session ( ISession )
         IDBRepository<IProduct> rep = Repository.Get<IProduct>();

         // Create new object of product
         rep.Create(new Product() { Name = productName });

         // get created object by name
         prod = rep.Query().Where(x => x.Name == productName).SingleOrDefault();

         // I HAVE ISSUE HERE
         // prod.Functions == NULL. It must be a new List<Function>()
         // Nhibernate don't create empty list for me and this property always null

         return prod;
    }

НО. Когда nhibernate закрывается и снова открывается, список будет создан и будет содержать 0 элементов.

Если я создам объект (Продукт) в том же сеансе и получу его после создания, bag будет иметь значение null.

Функция хранилища данных

public class DBRepository<T> : IDBRepository<T>
{
    protected ISession CurrentSession;

    public DBRepository(ISession session)
    {
        CurrentSession = session;
    }

    public void Create(T obj)
    {
        var tmp = CurrentSession.BeginTransaction();
        CurrentSession.Save(obj);
        tmp.Commit();
    }
}

1 Ответ

4 голосов
/ 03 октября 2011

Когда вы вызываете new Product(), ваш код создает экземпляр объекта, и свойство List <> начинает жизнь с нуля.NHibernate не может вам помочь - это то, что вы решили сделать (не переопределяя стандартное значение c'tor).

Кэш 1-го уровня NHibernate (краткое объяснение здесь ) сохраняет вашиобъект, когда вы фиксируете транзакцию, поэтому, когда вы находитесь в том же открытом сеансе, вы запрашиваете объект по его идентификатору. NHibernate пропускает получение объекта из базы данных и предоставляет вам тот же экземпляр объекта.Вы можете проверить это с помощью Object.ReferenceEquals(prodYouCreated, prodRetrievedFromRepository).

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

Надеюсь, это поможет,
Jonno

...