Skip navigation
Currently Being Moderated

failed to lazily initialize a collection of role

Aug 22, 2006 4:34 PM

I am using Spring and Hibernate 3. The problem I am running into is lazy loading, the session is getting blasted when Flex tries to create an object that has sets.

<set name="loans" inverse="true" lazy="true">
<key>
<column name="amortization_type_id" />
</key>
<one-to-many class="com.gcloans.dao.hibernate3.Loan" />
</set>

I don't want to have lazy="false" for memory issues. Any ideas.
 
Replies
  • Currently Being Moderated
    Aug 22, 2006 11:01 PM   in reply to sanclementetech
    Hi Ken,

    Do you have an associated data service destination for the Loan entity type that is also marked as lazy? If this property isn't marked as lazy in the data service config a deep traversal is done because we don't maintain long running Hibernate sessions.

    When you state that the session is getting blasted what exactly are you experiencing?

    Best,
    Seth
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 23, 2006 10:58 AM   in reply to sanclementetech
    Hi Ken,

    I think the issue is with our debug logging code (Message.*). We have some "pretty printer" logic which is trying to recursively dump out the state of any arguments and return values to the RemoteObject call. For your Hibernate entity object, this means it is trying to access the state of some properties which have not been initialized yet because they are lazily loaded. Since this is all happening after the remote object call has returned, the session is closed.

    If you can modify the code of your hibernate entity class to add your own custom toString method, it will skip this recursive pretty printer logic. Just makes ure your toString does not fetch the state of properties that have not been loaded (I usually have mine print the ids of the referenced objects for single valued relationships and you probably want to just forgo printing anything for collections since hibernate will not have fetched any state for them).

    Sorry for the problems... this pretty printer thing was added late in the game. I had kind of wanted an option to turn it on so it is off by default but we did not get that in.

    Jeff Vroom
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 23, 2006 6:07 PM   in reply to sanclementetech
    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
     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)