Page 1 of 3 123 LastLast
Results 1 to 10 of 21

Thread: A way to handle Hibernate's LazyLoading with remoting

  1. #1
    Join Date
    Dec 2005
    Location
    Argentina
    Posts
    73

    Default A way to handle Hibernate's LazyLoading with remoting

    Hello,
    I’m not sure if what I’m going to ask belongs here, if it doesn’t please let me know where should I put it.
    I’m looking for comments/suggestions on a problem I had and the solution I implemented.

    The application I work on has a 3 tier architecture:

    Eclipse RCP Client -- RMI --> Service Layer --> Dao Layer --> Hibernate --> DB

    What was really annoying me was the “depth” level of the object graph I was fetching from the DB. For example, in some scenario I needed a customer with all its relations and in other scenario I just needed its name and address. Being a RMI “jump” away hibernate’s lazy loading didn’t work, and I didn’t want to provide lots of method in the service interface to control this parameter, but neither did I want to send unnecessary big objects through the network.
    So what I did is to pass an Initializer from the client to the service layer to initialize the needed relations after the objects were retrieved from the DB, but before the transaction was commited. This extra parameter is passed as a Thread Local(client) - RemoteInvocation - Thread Local(server) attribute to avoid polluting the business interface.

    I have left some details out to keep this post readable, so please ask if there’s anything missing.

    Any comments will be greatly appreciated.
    Regards,
    Federico.

  2. #2
    Join Date
    Nov 2005
    Location
    Chicago
    Posts
    122

    Default

    Hi Frederico.

    That sounds like a very interesting solution. It seems transparent which is a great benefit. How do you handle the initializers? Do you have some way to set it up per method on the client side?

    Jess

  3. #3
    Join Date
    Dec 2005
    Location
    Argentina
    Posts
    73

    Default

    Hello Jess, thanks for your answer.
    I set up the initializers per method call as a thread local variable just before making the invocation. Then a special RemoteInvocationFactory is responsible for putting the initializer as an extra attribute in the remoteInvocation and cleaning the thread local variable.
    Do you want me to post some code?

    Regards,
    Federico.

  4. #4
    Join Date
    Nov 2005
    Location
    Chicago
    Posts
    122

    Default

    Actually it would be nice to look at the code. But I am wondering more about the initializers. How do you do the code for them? Do you do an anonymous implementation (like done with ActionListener)? Or do you have a set of these that have names, eg. 'CustomerCollectionInitializer', 'CustomerNoCollectionInitializer'? Hope this makes sense....

    Jess

  5. #5
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    Hi,

    I've been doing something similar for a while now and have found it works well. I haven't done anything like the threadlocal approach you talk about. I tend to consider the graph hydration level as part of the service contract so have no problem in including it in the interface.

    Maybe to address the other questions. I have a concept of a HydrationSpecification that contains two arrays, one of prefetch levels the other of post fetch levels. Each class in my domain model exposes a number of allowed levels. These level classes use OGNL to specify the actual properties which allows for quite complex loading situations (eg nested collections) to be handled quite well. My dao's then use the hydration specification by i) using the prefetch to add fetchMode's to the constructed criteria and ii) by using the post fetch to call initialize.

    Jonny

  6. #6
    Join Date
    Dec 2005
    Location
    Argentina
    Posts
    73

    Default

    Here’s one of them:

    public class PersonRoleInitPlan implements InitializationPlan<AbstractPerson> {
    public void init(AbstractPerson o) {
    Hibernate.initialize(o.getRoles());
    }
    }

    I could have initiliazed the roles collection by “iterating” it (to avoid coupling the domain with hibernate), for example:

    public void init(AbstractPerson o) {
    o.getRoles().size();
    }


    The anonymous approach seemed nice to me, but I’m using RMI, and using anonymous classes means it will also send the top level class through the network, something I’d like to avoid, so I ended with named initializers.

  7. #7
    Join Date
    Dec 2005
    Location
    Argentina
    Posts
    73

    Default

    Quote Originally Posted by jwray
    Hi,

    Maybe to address the other questions. I have a concept of a HydrationSpecification that contains two arrays, one of prefetch levels the other of post fetch levels. Each class in my domain model exposes a number of allowed levels. These level classes use OGNL to specify the actual properties which allows for quite complex loading situations (eg nested collections) to be handled quite well.

    Jonny
    Hello Johny,
    That´s interesting because it adds another level of customization to the dao. How do your classes expose the allowed levels?

    Federico.

  8. #8
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    Just via public static final class variables. For example,
    Code:
    public static final ObjectGraphHydrationSpecification TIME_READS_WELL = 
        new AssayPlateHydrationSpecification("htpPlateReads.{htpTimeReads.{well}}");
    The string passed to the constructor is an OGNL construct. This one means for all members of the collection htpPlateReads access the collection htpTimeReads and for all members of that collection get the well.

    Typically, each domain model class will have multiple allowed hydration levels. Some are valid both pre and post fetch, some only post fetch. The client of the services then passes the hydration levels it needs to the service. In this way the division of responsibilty is clear. Domain model classes are responsible for defining allowed levels. Service clients are responsible for specifying which levels they require. DAO's are responsible for interpreting the levels and doing whatever is needed to get the data.

    Quote Originally Posted by fschroder
    Hello Johny,
    That´s interesting because it adds another level of customization to the dao. How do your classes expose the allowed levels?

    Federico.

  9. #9
    Join Date
    Oct 2004
    Location
    Herndon, VA, US
    Posts
    648

    Default

    Interesting topic. I am working on a project that will need to support both Web and rich clients. One approach I've been pondering about lately is to advise the domain model classes deployed to the client side so that methods like getRoles() would lazily and transparently make a RMI call to get the role objects - similar to how Hibernate implements the lazy-loading on the server side. I haven't got around to actually prototype it yet, so I guess the performance implication is still hard to say, which of course would be the biggest concern.
    --Jing Xue

  10. #10
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    I could be wrong but this almost sounds like it might lead to one of the initial problems that occured with people using entity beans in ejb. Too many remote calls for data access leading to awful performance, which in turn lead to the DTO pattern that basically advises locally populating an object with data before shipping across a wire.

    Jonny

    Quote Originally Posted by manifoldronin
    Interesting topic. I am working on a project that will need to support both Web and rich clients. One approach I've been pondering about lately is to advise the domain model classes deployed to the client side so that methods like getRoles() would lazily and transparently make a RMI call to get the role objects - similar to how Hibernate implements the lazy-loading on the server side. I haven't got around to actually prototype it yet, so I guess the performance implication is still hard to say, which of course would be the biggest concern.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •