Oops, forgot two points:
 
1)  The lazy-loaded City object in the example is null.  (i.e.
state.Capital.Name would throw a NullReferenceException if lazy-loading
weren't enabled).
2)  The public properties in the State and City classes should both be
virtual.

________________________________

From: Wyatt, Mike [mailto:[EMAIL PROTECTED] 
Sent: Monday, November 10, 2008 3:26 PM
To: [email protected]
Subject: Lazy-Loaded null reference properties



Class State contains a reference to class City.  That reference is
configured in the ResultMap to be lazy-loaded.  Class City has a simple
string property called Name.  

    public class State 
    { 
        private City _capital; 
        public City Capital { get { return _capital; } set { _capital =
value; } }
    } 

    public class City 
    { 
        private string _name; 
        public string Name { get { return _name; } set { _name= value; }
}
    } 

    State state = _mapper.QueryForObject<State> ( "GetState", "WI" ); 
    Console.Write( state.Capital.Name ); 

Accessing state.Capital.Name throws a "TargetException: Non-static
method requires a target" exception:  

    [TargetException: Non-static method requires a target.] 
       System.Reflection.RuntimeMethodInfo.CheckConsistency(Object
target) +7515801 
       System.Reflection.RuntimeMethodInfo.Invoke(Object obj,
BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
culture, Boolean     skipVisibilityChecks) +105

       System.Reflection.RuntimeMethodInfo.Invoke(Object obj,
BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo
culture) +29

 
IBatisNet.DataMapper.Proxy.LazyLoadInterceptor.Intercept(IInvocation
invocation, Object[] arguments) +391 
 
CProxyTypeState_System_Runtime_SerializationISerializable1.get_Name()
+190 
    [MethodInvocationException: Invocation of method 'Name' in
CProxyTypeState_System_Runtime_SerializationISerializable1 threw an
exception]

I'm using iBATIS in a web app that uses NVelocity to render web pages.
NVelocity will ignore NullReferenceExceptions, but not TargetExceptions,
when rendering dynamic tags (i.e. $state.City.Name).

My proposed solution is simple.  In
IBatisNet.DataMapper.Proxy.LazyLoadInterceptor, the invocation of the
returnValue on line 133 should be modified to throw a
NullReferenceException if _lazyLoadedItem is null.

*Before* 
        object returnValue = invocation.Method.Invoke( _lazyLoadedItem,
arguments);             

*After* 
        if( _lazyLoadedItem == null ) 
        { 
                throw new NullReferenceException(); 
        } 

        object returnValue = invocation.Method.Invoke( _lazyLoadedItem,
arguments);             

Thoughts on this solution or possible workarounds? 

Reply via email to