You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-cs@ibatis.apache.org by "Wyatt, Mike" <Mi...@quadsystems.com> on 2008/11/10 22:26:24 UTC
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?
RE: Lazy-Loaded null reference properties
Posted by "Wyatt, Mike" <Mi...@quadsystems.com>.
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:Michael.Wyatt@quadsystems.com]
Sent: Monday, November 10, 2008 3:26 PM
To: user-cs@ibatis.apache.org
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?