开发者

nhibernate. Bag is null after creation in same session

I have the object, which contain the list of objects.

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; }
}

Mapped list of objects ( IList < IFunction > ):

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

Code :

I try create a new object of 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;
    }

BUT. When nhibernate session close and open again, the list will be created and have 0 items.

If I create an object(Product) in the same session and get it after creation, bag will be null.

Function of data repository

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();
    }
}


When you are calling new Product(), your code is instantiating an object and the List<> property begins life as null. NHibernate can't help you there - it's what you've decided to do (by not overriding the default c'tor).

NHibernate's 1st level cache (short explanation here) saves your object when you commit the transaction, so when in the same open session you ask for the object by its ID NHibernate skips getting the entity from the database and serves you that same instantiated object. You can test that with Object.ReferenceEquals(prodYouCreated, prodRetrievedFromRepository).

When you close the session the 1st level cache is cleared and next time you query NHibernate fetches the data and builds the object itself - it chooses to give you back a zero-length list instead of null. That is the default behaviour.

Hope this helps,
Jonno

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜