Sorry, I did mean to include some more sample details in my email but was scrambling on some other tasks and wanted to at least get the question fired off…
Specifically, we have set up a number of domain class properties to be typed as IList so that we can lazy load, eg.
public IList ProdAttrList
In our maps, we have configured ibatis to lazy load this list, derived from a custom collection class, eg.
<result property="ProdAttrList" lazyLoad="true" column="SKU" select="ProductAttribute.ListBySku" />
Where that select attribute points at a statement with a result type of the custom collection class, eg.
<select id="ProductAttribute.ListBySku" listClass="ProductAttributeCollection" resultMap="ProductAttribute">
Older versions of ibatis used a rather different mechanism for lazy-loading lists where as soon as lazy-load was turned on ibatis would use a specific list class of its own. Now, however, with the new proxy-based logic, it is trying to subclass the domain class property type, whereas it should be trying to subclass the listClass-specified type. If you take a look at the code in the method it looks very much like a simple error during typing that was missed in the tests, because the logic of the method goes through specific steps to check for valid casts into the domain class property, checks if a listClass has been provided, and then, if so, promptly ignores the type stated by the listClass and tries to proxy the type defined by the domain class, which, as you might expect for IList, fails spectacularly.
The fix I outlined is simple, and, based on the logic executing before it, is what I suspect was intended to be in the code in the first place.
From: Gilles Bayon
Sent: Wednesday, May 10, 2006 9:53 AM
Subject: Re: LazyLoadProxyFactory bug? Ignores listClass during attempt to build proxy
I known that I must polish the Lazy load
Could you give me an example of you domain objects and the mapping you are using.
On 5/10/06, Jeremy Gray <firstname.lastname@example.org> wrote:
I think I may have found a bug in the more recent LazyLoadProxyFactory. If the list type in the domain object implements IList and a listClass is specified in the sql map, ibatis ignores the list class setting and instead attempts to build a proxy for the list type defined in the domain object. In our case, the domain objects for which we have been lazy loading properties have had their exposed types set to IList (so that we could trade off custom collections against lazy-loaded lists just by changing the config) but the sql map has been set to use the custom collection. Older versions of ibatis would ignore the lazyload attribute when a listclass was present, but with the new proxy-generating codebase, it reverses this, obeying the lazyload but ignoring the listclass and trying to instead proxy the IList (which of course fails).
The fix, based on my limited testing today, is quite simple, involving a one line change from this (currently on line 95):
proxy = ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(typeProxified, handler, Type.EmptyTypes);
proxy = ProxyGeneratorFactory.GetProxyGenerator().CreateClassProxy(mappedStatement.Statement.ListClass, handler, Type.EmptyTypes);