Hi Ken,
My apologies, I think I was off by one-level in my
understanding of the problem. From looking at the stack trace more
carefully, I believe the issue is that you do a query on hibernate
to return a Contact instance. It is not that this instance has
properties which point to objects which are not initialized, but
that it is not initialized itself. When the debug logging tries to
fetch the Contact instance to call its toString method, it is
failing to retrieve the "real" populated Contact instance.
This problem is more structural since even if you turn off
debugging, the state of that object has not been fetched so this
would just move the error elsewhere. I think that in this case, you
just have to initialize the Contact instance in your RemoteObject
before returning it. Otherwise, it is just a hollow shell which
only has the "id" of the Contact - there is no data there yet. This
might be a simple matter of trying to fetch some property of the
Contact before it gets returned. There is also the
"Hibernate.initialize(<your-obj>)" method which you could try
as well to do this more generically.
The other problem I think you'll run into though is that the
class name of the returned object is not what you'd expect. Instead
of it being:
com.gcloans.dao.hibernate3.Contact
it is actually:
com.gcloans.dao.hibernate3.Contact$$EnhancerByCGLIB$$aa099d5f
This is hibernate's generated class wrapper which fetches the
state of the real contact the first time you try to access it.
Unfortunately this wrapper class messes up the RemoteClass mapping
if you are trying to map this to a concrete type in ActionScript.
It may also mess up the serialization even if you are expecting
that to come over as a weak typed "Object" in ActionScript (I
believe it at least has an extra "implementation" property). If you
do run into those problems, you could try using the solution we
added for "Data Management Services". You'd have to simply add this
line to some code which gets initialized before your remote object
gets returned:
import org.hibernate.proxy.HibernateProxy;
import flex.messaging.io.PropertyProxyRegistry;
import flex.data.assemblers.HibernatePropertyProxy;
....
PropertyProxyRegistry.getRegistry().register(HibernateProxy.class,
new HibernatePropertyProxy());
This basically means that whenever AMF encounters an object
which implements the "HibernateProxy" interface, it uses this
HibernatePropertyProxy class to help serialize that object. Instead
of serializing the CGLIB wrapper class, it gets the implementation
class from underneath that and serializes that object. This does
assume that object has already had its public properties
initialized so make sure to access some property of your Contact
instance before closing the hibernate session.
Finally, I believe it is also possible to configure hibernate
so it does not use CGLIB generated wrappers if this is getting too
complicated. I hope this helps,
Jeff