Hi!
Quote:
No, LIE doesn't contain the object that caused it. I'm not sure even what you could use it for. I suppose we could put the class name and the id into the exception, for debugging purposes. We can't put the referencing entity there because we don't know it.
The abstract base class AbstractPersistentCollection that are one of two classes in the NHibernate assembly that throws LIE actually holds the referencing entity instance, and a small modification on how LIE is instantiated made it possible to get more context information into the exception.
Code:
/// <summary>
/// Initialize the collection, if possible, wrapping any exceptions
/// in a runtime exception
/// </summary>
/// <param name="writing">currently obsolete</param>
/// <exception cref="LazyInitializationException">if we cannot initialize</exception>
protected void Initialize(bool writing)
{
if (!initialized)
{
if (initializing) throw new LazyInitializationException(owner, "cannot access loading collection", null);
if (IsConnectedToSession)
{
if (session.IsConnected)
{
try
{
session.InitializeCollection(this, writing);
}
catch (Exception e)
{
log.Error("Failed to lazily initialize a collection", e);
throw new LazyInitializationException(owner, "Failed to lazily initialize a collection", e);
}
}
else
{
throw new LazyInitializationException(owner, "Failed to lazily initialize a collection - session is disconnected", null);
}
}
else
{
throw new LazyInitializationException(owner, "Failed to lazily initialize a collection - no session", null);
}
}
}
The other class throwing LIE is the LazyInitializer. This class has information about the referencing entity's type and the object id:
Code:
/// <summary>
/// Perform an ImmediateLoad of the actual object for the Proxy.
/// </summary>
/// <exception cref="HibernateException">
/// Thrown when the Proxy has no Session or the Session is closed or disconnected.
/// </exception>
public void Initialize()
{
if (!initialized)
{
if (_session == null)
{
throw new LazyInitializationException(_persistentClass, _id, "Could not initialize proxy - no Session.");
}
else if (!_session.IsOpen)
{
throw new LazyInitializationException(_persistentClass, _id, "Could not initialize proxy - the owning Session was closed.");
}
else if (!_session.IsConnected)
{
throw new LazyInitializationException(_persistentClass, _id, "Could not initialize proxy - the owning Session is disconnected.");
}
else
{
_target = _session.ImmediateLoad(_persistentClass, _id);
CheckTargetState();
initialized = true;
}
}
else
{
CheckTargetState();
}
}
So all the information is really there and I would like to understand why this information should not be provided when throwing LIE. With more context information, I can now make lazy loading automatic when accessing a lazy property without a session, with owning session closed etc. In my modified version of NHibernate I've got this information available, and can handle the exception through reflection and AOP instead of the tedious try-catch statements that get scattered around in the presentation model.