I'm wrestling with an NHibernate issue I never had in Hibernate. I've got an object with a lazy loaded collection. I'm loading up the object in one session and then I want to reattach it in another session and initialise the lazily loaded collection. However I keep getting an 'collection is not associated with a session' error. The code to merge is very simple:
/// <summary>
/// Loads all the lazy collections in the sample types
/// </summary>
/// <param name="sampleTypes"></param>
public static void FullyLoadSampleTypes(ICollection<SampleType> sampleTypes)
{
using (SessionScopeWrapper ssw = new SessionScopeWrapper(FlushAction.Never))
{
sampleTypes.ForEach(st =>
{
if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs))
{
ssw.Session.Merge(st);
NHibernateUtil.Initialize(st.MasterKeyValuePairs);
}
});
}
}
The merge executes but the Initialize call throws the 'not associated with a session error' - note that I'm on Hibernate 3 (locked in by a dependency on Activerecord at the moment). I would have thought that the Merge would reassociate the sampleType object and it's collection?
Can anyone please shed some light on the situation for me? Note that I can load the whole thing (including the lazy collection) in one session but I need to know how to reattach and lazily load a collection for NHibernate in general.
Cheers,
Neil
Merge
is for copying your detached entity object into the corresponding other object from the second session. This corresponding object into second session is then returned by Merge
.
Your detached object is still detached afterwards.
Your code would not crash if you were doing:
if (!NHibernateUtil.IsInitialized(st.MasterKeyValuePairs))
{
var merged = ssw.Session.Merge(st);
NHibernateUtil.Initialize(merged.MasterKeyValuePairs);
}
This is documented in the Merge
xml comments (emphasis mine).
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session.
Maybe this does not suit you. If you want your detached object to be associated with the second session, you need to Update
it in this second session. Granted, the Update
xml comments are not explicit about that. Beware nonetheless (from <remarks>
):
If there is a persistent instance with the same identifier, an exception is thrown.
Meaning that if your second session has already loaded the same entity, Update
will fail.