Ok Thanks for the feedback
Our first implementation based on this solution seems to work Wouter _____ Van: MCCORMICK, Paul [mailto:[EMAIL PROTECTED] Verzonden: maandag 19 maart 2007 3:02 Aan: user-java@ibatis.apache.org Onderwerp: RE: Lazy loading issues I'll give you some of the sudo code that I used to overcome lazy loading of 1 to 1 relationships. I had to write extra code to allow lazy loaded objects to be serializable and cloneable. The code has nothing to do with lazy loading of lists. All objects loaded from the database implement the IBaseDomain interface. interface IBaseDomain { Integer id // The primary key which is never null Integer versionId // Used of optomistic locking boolean setNewCalled // Used when the id and versionId have been set to null by client code. } Here is the ResultObjectFactory used. Quite simple, just enhances anything that implements IBaseDomain. public final class EmitsResultObjectFactory implements ResultObjectFactory { public final Object createInstance(String arg0, Class clazz) throws InstantiationException, IllegalAccessException { if (IBaseDomain.class.isAssignableFrom(clazz)) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallbackFilter(EnhancedBaseDomainCallbackFilter.instance); enhancer.setCallbacks(EnhancedBaseDomainCallbackFilter.callbacks); return enhancer.create(); } else { return null; } } public void setProperty(String arg0, String arg1) {} } ----------------------------------------------------------- public final class EnhancedBaseDomainCallbackFilter implements CallbackFilter, MethodInterceptor, Serializable { private EnhancedBaseDomainCallbackFilter() { } public static final EnhancedBaseDomainCallbackFilter instance = new EnhancedBaseDomainCallbackFilter(); public static final Callback[] callbacks = { NoOpCallback.INSTANCE, instance }; public final int accept(Method method) { if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 && IBaseDomain.class.isAssignableFrom(method.getReturnType())) { return 1; // BaseDomain return types are intercepted. } return 0; // the No operation interceptor. Does nothing. } /** * Allows using the enhancementEnabled ibatis option. This option allows the lazy loading of single objects ( and not just Lists ). * * e.g the following method can be lazy loaded: public Party getParty(); * * A problem occurs if calling the "public Party getParty()" should return null. Instead of null being returned a 'wrapped null' is returned. This MethodInterceptor fixes this * feature/bug. */ public final Object intercept(final Object object, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable { Object obj = proxy.invokeSuper(object, args); if ((obj == null) || (!(obj instanceof IBaseDomain))) { return obj; } IBaseDomain baseDomain = (IBaseDomain) obj; // All Enhanced objects implement Factory. if (baseDomain instanceof Factory) { // If the primary key is null then the object is null unless the client code called setNew() if (baseDomain.getId() == null) { try { // If baseDomain.setNew() is called then the object is valid. If not then its a return null instead of the proxy. if (!baseDomain.isSetNewCalled()) { return null; } // There is a bug in cg lib that can cause a Null Pointer to be thrown on a cloned enhanced object. Don't know why but this is a temp fix. } catch (NullPointerException e) { Log log = LogFactory.getLog(EnhancedBaseDomainCallbackFilter.class); log.debug("EnhancedBaseDomainCallbackFilter.intercept caught NullPointerException on method " + method.getName() + " object:" + baseDomain.getClass().getName()); return null; } } } return baseDomain; } private interface NoOpCallback extends NoOp, Serializable { /** * A thread-safe singleton instance of the <code>NoOpCallback</code> callback. */ public static final NoOpCallback INSTANCE = new NoOpCallback() { }; } } ----------------------------------------------------------- I changed the Ibatis class EnhancedLazyResultLoader. 1) I had to make an inner class Serializable. This involved making the field that links to the jdbc connection transient. I then had to put my application code into this class to set this transient field. Thats a hack that you may want to improve on. 2) Changed the EnhancedLazyResultLoaderImpl.loadResult() method to only create proxy objects for IBaseDomain results ( that are not abstract). The reason for not lazy loading abstract classes is because the instanceof does not work as expected when comparing to a concrete class. Here is the method code. I'll attach a file of the whole class also but most of it is not relevent. public Object loadResult() throws SQLException { if (...) .... } else if (Collection.class.isAssignableFrom(targetType)) { ..... // This is my custom code for lazy loading 1 to 1 relationships. } else if ( IBaseDomain.class.isAssignableFrom(targetType) && !Modifier.isAbstract(targetType.getModifiers())) { return Enhancer.create(targetType, new Class[] { IBaseDomain.class } , this); } else { loadObject(); return resultObject; } } I hope this helps, Paul _____ From: Wouter Roose [mailto:[EMAIL PROTECTED] Sent: Friday, 16 March 2007 6:13 PM To: user-java@ibatis.apache.org Subject: RE: Lazy loading issues Anybody? _____ Van: Wouter Roose [mailto:[EMAIL PROTECTED] Verzonden: maandag 12 maart 2007 8:49 Aan: user-java@ibatis.apache.org Onderwerp: Lazy loading issues Hello Concerning <http://opensource.atlassian.com/confluence/oss/display/IBATIS/Lazy+loading+ issues> http://opensource.atlassian.com/confluence/oss/display/IBATIS/Lazy+loading+i ssues I encountered the second problem. Could somebody be so kind to add some coding examples to the solution on the wiki? especially the one with the ResultObjectFactory. As I'm not an expert iBATIS developer it is difficult to implement this solution based on this explanation Regards, Wouter _____ Disclaimer <http://www.minfin.fgov.be/disclaimer.htm> _____ Disclaimer <http://www.minfin.fgov.be/disclaimer.htm> "DISCLAIMER: This email, including any attachments, is intended only for use by the addressee(s) and may contain confidential and/or personal information and may also be the subject of legal privilege. If you are not the intended recipient, you must not disclose or use the information contained in it. In this case, please let me know by return email, delete the message permanently from your system and destroy any copies. Before you take any action based upon advice and/or information contained in this email you should carefully consider the advice and information and consider obtaining relevant independent advice. ---------------------------------------------------------------- - Disclaimer: http://www.minfin.fgov.be/disclaimer.htm