LazyLoad fails after clearing cache of session
Description
Environment
Attachments
Activity

Jenar September 5, 2011 at 4:39 AM
Re:Fabio Maulo:
Accoirding to http://nhforge.org/doc/nh/en/index.html#batch it is also importand that lazy loading should be working after calling session.clear().
Batch inserts "When making new objects persistent, you must Flush() and then Clear() the session regularly, to control the size of the first-level cache. "
ISession session = sessionFactory.openSession();
ITransaction tx = session.BeginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.Save(customer);
if ( i % 20 == 0 ) { //20, same as the ADO batch size
//flush a batch of inserts and release memory:
session.Flush();
session.Clear();
}
}
tx.Commit();
session.Close();
Could you take care of this issue?

Jenar July 18, 2011 at 8:02 AM
Created new ticket for this: https://nhibernate.jira.com/browse/NH-2797

Jenar July 15, 2011 at 7:18 AM
There is another problem i have found.
How to refresh objects from SQL/HQL-query without calling session.Clear()?
Because if you call nativeSQL second time with different parameters,
what you become are results from first call. Let me show you this with "pseudo code":
using (session...){
//Call 1
Int32 Param1 = 1;
List<myObject> list = session.GetNamedQuery("SQL_myQuery")
.SetInt32("PARAM1", (Int32)Param1)
.List<myObject>();
//Call2: without session.Clear() you will became results from Call1
//and session.Refresh() is not working because myObject is not mapped to table, but to sql
Param1 = 2;
list = session.GetNamedQuery("SQL_myQuery")
.SetInt32("Param1", (Int32)Param1)
.List<myObject>();
}
<sql-query name="SQL_myQuery">
<return class="Model.BO.myObject, Model.BO" ></return>
select * from GETSOMEDATA(ARAM1);-- ie Stored Procedure
</sql-query>
Have you idea how to do this in the same session without session.clear() ?

Jenar July 15, 2011 at 6:23 AM
Yes i agree with you that new method "session.ClearAndRefresh() would be more obvious". It will clean up cache and "reassociate" entities with existing session. That will be great.
But decision depends on you
PS.For now i will try not to use session.clear()
Thank you for your time and have a nice day

Julian Maughan July 15, 2011 at 5:39 AM
Jenar, I don't think that would be a good improvement. Clear() and Refresh() have distinct and well-defined behaviours. If you call session.Clear(), it seems obvious to me that any entities loaded by the Session are not longer managed by that Session. It would be confusing if Refresh() was also called internally. A ClearAndRefresh() method would be more obvious, but I don't think it is really necessary. Rather just create a new Session - they are intended to be lightweight.
Also take note of the documentation on ISession.Refresh(object):
It is inadvisable to use this to implement long-running sessions that span many
business tasks.
I agree with you that it would be better if NHibernate could disassociate the entities from the Session cleanly - without the exception. I presume that entities would be cleanly disassociated on Session.Close??
Details
Details
Assignee
Reporter

Lazyproperties/Collections are not lazyloaded after session cache was cleared.
ClassC result;
using (ISession session = this.OpenSession()) {
result = session.Get<ClassC>(1);
session.Clear(); //Clear session cache,after this lazy props throws exeptions
string s = result.classB.classA.Text;
Assert.AreEqual("Test ClassA 1", s);
}
See Attached Test.
It would be great, if fix for it, could be included in next RC or stable.