These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: lazy loading and retrieval of newly saved data
PostPosted: Tue Jun 17, 2008 12:39 pm 
Beginner
Beginner

Joined: Tue Jan 22, 2008 11:33 am
Posts: 46
Hi ,

I've been looking for quite a while cannot find the solution to for a strange behaviour of my application. I can reproduce it in a small example.

I have two OrganizationalUnit und Type.

OrganizationalUnit contains Type als Foreign Key, which mean each OrganizationalUnit is of a certain type Typ. After retrieving entities I do not close the session but instead leave the session to reuse it
- Mapping File of OrganizationalUnit looks like that :

Code:
<class name="xxx.OrganizationalUnit,xxx" table="OrganizationalUnit" lazy="false">

    <id name="OrganizationalUnitId" column="OrganizationalUnitId" type="int">

      <generator class="increment" />

    </id>

    <many-to-one name="TypeId" cascade="none" column="TypeId" not-null="true" />

</class>



- Mapping File of Type looks like that

Code:
<class name="xxx.Type,xxx" table="Type" lazy="false">

    <id name="TypeId" column="TypeId" type="string">

      <generator class="assigned" />

    </id>

    <bag name="FkOrganizationalUnitType" inverse="true" lazy="true" cascade="all">

      <key column="TypeId" />

      <one-to-many class="xxx.OrganizationalUnit,xxx" />

    </bag>

  </class>




Now, what am I doing?:



Code:
IList types = BusinessObjectFactory<DC.Type>.GetItems; // retrieve all  “Type”-Objects

// each Object contains the  Attribute FkOrganizationalUnitType being a list of OrganizationalUnits which are of the specific type



DC.OrganizationalUnit orgUnit = new DC.OrganizationalUnit((DC.Type)types[0]); // now I create a new OrganizationalUnit of Type types[0]

orgUnit.Save(orgUnit); //I save the  OrganizationalUnit in the database – works fine; entry is persistent

IList typesNew = BusinessObjectFactory<DC.Type>.GetItems; // now I try to retrieve the Objects of the entity “type“ again



Now I would like that the Attribut „FkOrganizationalUnitType“ of typesNew[0] has one more entry then types[0] – the one which we have created and saved. Unfortunately the FkOrganizationalUnitType are identical and only after starting the application again the list in FkOrganizationalUnitType will be complete



Here ist he getItems Routine:

Code:
public static IList GetItems

        {

            get

            {

                IList items = null;

                ISession session = SessionProvider.Instance.GetSession();

                ITransaction trans = null;



                try

                {

                    trans = session.BeginTransaction();

                    items = session.CreateCriteria(typeof(T)).List();

                    trans.Commit();

                    foreach (object currentEntry in items) ((T)currentEntry).PersistenceInfo = PersistenceStatus.persistent;

                    return items;

                }

               

                catch (Exception ex)

                {

                    trans.Rollback();

                    throw new DataAccessException("Error getting items", ex);

                }

                finally

                {

                    SessionProvider.Instance.CloseSession();

                }

            }

        }



As I said the session retrieved here, is reused because the first call did not close the session. Otherwise I could not work with lazy-loading. How can I do both lazy loading and retrieve entries, . Do you have an Idea what I could do to make it work right???

Thanks for your help in advance
antoschka


Top
 Profile  
 
 Post subject: SOLVED!
PostPosted: Thu Jun 19, 2008 4:39 am 
Beginner
Beginner

Joined: Tue Jan 22, 2008 11:33 am
Posts: 46
Hi,

I found a solution to the problem and it's pretty straight forward. First I have to point out that GetItems-Routine seems to close the session, but trigger-constant named reuseSession avoids closing it.
So the code is a kind of misleading, just by reading it.

So we end up having still an open session to retrieve lazy-Collections. In order to retrieve at runtime lazy-Collection-Items which were added after the session was opened, we have to upsize the GetItems-Routine to Method which receives a bool-Parameter ClearSessionFirst.

If this Parameter is set, the open session is emptied before loading it again. You can achieve that by simply calling
session.Clear(). So the new GetItem Method looks like that:
Code:
public static T GetItem(object id, bool clearSessionFirst)
        {
            ISession session = SessionProvider.Instance.GetSession();
            if (clearSessionFirst) session.Clear();
            T item;
            System.Type specifiedType = typeof(T);
            try
            {
                //return session.Load(pType, id);
                item = (T)session.Load(specifiedType, id);
                item.PersistenceInfo = PersistenceStatus.persistent;
                return item;

            }
            catch (Exception ex)
            {
                throw new DataAccessException("Error getting item", ex);
            }
            finally
            {
                SessionProvider.Instance.CloseSession();
            }
        }


In order to leave the old GetItem-callings and the logic behind untouched, we rewrite the Method like that:
Code:
public static T GetItem(object id)
        {
            return GetItem(id, false);
        }


Have fun with NHibernate

antoschka


Top
 Profile  
 
 Post subject: SOLVED!
PostPosted: Thu Jun 19, 2008 4:40 am 
Beginner
Beginner

Joined: Tue Jan 22, 2008 11:33 am
Posts: 46
Hi,

I found a solution to the problem and it's pretty straight forward. First I have to point out that GetItems-Routine seems to close the session, but trigger-constant named reuseSession avoids closing it.
So the code is a kind of misleading, just by reading it.

So we end up having still an open session to retrieve lazy-Collections. In order to retrieve at runtime lazy-Collection-Items which were added after the session was opened, we have to upsize the GetItems-Routine to Method which receives a bool-Parameter ClearSessionFirst.

If this Parameter is set, the open session is emptied before loading it again. You can achieve that by simply calling
session.Clear(). So the new GetItem Method looks like that:
Code:
public static T GetItem(object id, bool clearSessionFirst)
        {
            ISession session = SessionProvider.Instance.GetSession();
            if (clearSessionFirst) session.Clear();
            T item;
            System.Type specifiedType = typeof(T);
            try
            {
                //return session.Load(pType, id);
                item = (T)session.Load(specifiedType, id);
                item.PersistenceInfo = PersistenceStatus.persistent;
                return item;

            }
            catch (Exception ex)
            {
                throw new DataAccessException("Error getting item", ex);
            }
            finally
            {
                SessionProvider.Instance.CloseSession();
            }
        }


In order to leave the old GetItem-callings with their signature untouched, we rewrite this Method like that:
Code:
public static T GetItem(object id)
        {
            return GetItem(id, false);
        }


Have fun with NHibernate

antoschka


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.