Looks like I am talking to myself here.:-(
Finally I get a chance to do furthur investigation around this problem.
Here is why, in getProxy code of CGLIBLazyInitializer,
Code:
final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
persistentClass, interfaces, id, getIdentifierMethod, setIdentifierMethod, session);
final HibernateProxy proxy = (HibernateProxy) Enhancer.create(
(interfaces.length==1) ?
persistentClass :
null,
interfaces,
instance
);
When I use iterate() method to find this class, it only create an id and super-interface so it doesn't know all the subclass this particular id is implementing. So it passes every conceivable sub-interfaces to CGLib. So the proxy it returns contains all the interfaces regarless this id(instance) implemented or not. As I specified before, when invoking the method it could go to the wrong place.
Here is my hack to this problem since I don't think there is an esay way to re-narrow the interfaces after user get hold on this object's reference. Come think of it, it might be the IteratorImp's job to narrow the interface which should be doable.
Anyway, in intercept(....) method do the following will work:
Code:
Object o = getImplementation();
//find the real method to be invoking on instead of the wrong interface one
Method implMethod = o.getClass().getMethod(method.getName(), method.getParameterTypes());
return implMethod.invoke(o,args);
//this will break
// return proxy.invoke( getImplementation(), args );
Please remember this is my work-around right now since it defeats the purpose of using CGLib doing byte code enhacement.