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

Thread: Hibernate and lazy load

  1. #1

    Default Hibernate and lazy load

    Hello,

    Here is my situation. I have three classes A, B, and C. Class A has a collection of B and B has a collection of C. I'm using Hibernate for persistence. I have mapped the collections as lazy - since most of them I don't need to retrieve the entire graph. I have DAO classes for each A, B, and C. Each DAO classes extends HibernateDaoSupport.

    My problem is, for one case I need to retrieve the entire graph. After rereading the the docs and the forums, I realize that HibernateDaoSupport opens and closes the session for me and to avoid a LazyInitializationException I need to reattach the object to a session. Fair enough.

    My question, is would it be a good idea to create an Intercepter on A.getB() and B.getC() that would make a call to Hibernate.initialize() ?

    If not, or if there is a better idea, could someone direct me to sample code? I've looked at the Spring samples but there does not appear to be an example of using Hibernate with lazy collections.

    Thanks.

  2. #2
    Join Date
    Aug 2004
    Location
    San Mateo, CA
    Posts
    1,265

    Default

    You could explicitly touch the relationship methods within your DAO or the enclosing transaction from service layer. Or you could use a fetch join. I don't much like the interceptor approach: seems a bit too much magic vs these simpler techniques.
    Rod Johnson - GM, SpringSource Division, VMware
    http://www.springsource.com
    Spring From the Source

  3. #3
    Join Date
    Apr 2005
    Posts
    12

    Default

    I have read about two possible solutions to this problem:

    1) Look at the OpenSessionInView pattern that is on the hibernate website (you can also try searching this forum for the same pattern). Basically, this pattern will do essentially what you want so that your view can be totally naive as to the lazy loading of data. The drawback to this approach is that because the DAO/persistance will be accessed outside of the service/business tier you won't have transaction coverage over the access.

    2) The book "Pro Spring" describes a little bit about a lazy loading strategy but it involves having your presentation tier tell the business tier whether it needs the "whole" object loaded or not. Thus, in your example you would probably have a method in your business tier that would be like "getB( Integer bId, boolean loadAll )". As previously mentioned the drawback is that your presentation tier must have some knowledge as to whether it needs everything or not and you are essentially doing some amount of performance coding in the presentation tier AND your presentation tier needs to be smart enough to only access those lazy fields if you have done a loadAll. The pro of this solution is that it is still demarcated by the transactions in the business tier.

    Any thoughts/other solutions?

  4. #4
    Join Date
    Apr 2005
    Posts
    12

    Default

    Sweet... Rod Johnson... love your work

  5. #5

    Default

    Thanks for the quick replies

  6. #6

    Default

    Or you could use a fetch join
    Actually I tried that and it did not seem to work. I will go back and investigate that route. BTW, I'm fairly new to Hibernate.

    Thanks again.

  7. #7

    Default

    ok, I've added a method to my dao to retrieve with a fetch join

    Code:
    public List getAll(){
       return getHibernateTemplate().find("select name from A " +
                    "join fetch B " +
                    "join fetch C ");
    This produces LazyInitializationException when I attempt to call A.getB()

    Looking into Hibernate in Action I read "Hibernate currently limits you to fetching just one collection eagerly". I am using Hibernate 2.1.8 not 3.

    If I change my getAll() to

    Code:
    public List getAll(){
       return getHibernateTemplate().find("select name from A " +
                    "join fetch B " +
                    "join C ");
    then as expected I get LazyInitializationException when I call B.getC().

    So then is it fair to say that because of a limitation of Hibernate I need to find an alternative to the much simplier solution of using fetch join?

    Thanks.

  8. #8
    Join Date
    Aug 2004
    Location
    Germany, Magdeburg
    Posts
    279

    Default

    My problem is, for one case I need to retrieve the entire graph.
    What is that case for? Where does the case occurs and who is responsible for this case in first place (object wise)? Normally you use the same session as long as you have to read datas from the database. Mostly you go for the following rule: One request, one thread, one session. Also all related reading should be preferable done inside a single (possibly read only) transaction. Otherwise you might sitting in hells kitchen when you face unpredictable and unmanageable data inconsistency.


    My question, is would it be a good idea to create an Intercepter on A.getB() and B.getC() that would make a call to Hibernate.initialize() ?
    Sounds not that good to me. But I never used such code anyways, so I am not the right person to make a judgment. ;-)


    If not, or if there is a better idea, could someone direct me to sample code? I've looked at the Spring samples but there does not appear to be an example of using Hibernate with lazy collections.
    Can you tell us a bit more about the use-case and the related context, the need for such retrieval of the entire graph exist? Would help... . Also I would like to know how your transactions are managed. Do you use any caching strategy?


    Cheers,

    Martin (Kersten)

  9. #9
    Join Date
    Apr 2005
    Posts
    12

    Default

    This thread might be of interest to you:
    http://www.newsarch.com/archive/mail.../msg03823.html

  10. #10
    Join Date
    Apr 2005
    Location
    Bristol, UK
    Posts
    3

    Default

    If you knew there existed at least one B for each A then you could retrieve the entire graph with one query.

    Code:
    from B b join fetch b.a join fetch b.c
    You are only allowed to eagerly fetch one collection in a query, but are able to "fetch as many one-to-one or many-to-one associations as you like".

    Then you'll need to make the results distinct, then process the collection to get all the A's.

    This might not be appropriate for every situation as I don't know how efficient all the collection processing will be for large result sets.

Similar Threads

  1. Replies: 2
    Last Post: Dec 8th, 2005, 09:00 AM
  2. how to use hibernate lazy loading with spring transaction
    By tanmoy.chakraborty in forum Data
    Replies: 1
    Last Post: Oct 11th, 2005, 02:07 AM
  3. Hibernate and Lazy Loading.
    By cmrudd in forum Data
    Replies: 1
    Last Post: Oct 3rd, 2005, 03:58 AM
  4. Hibernate and lazy load
    By mfuller in forum Data
    Replies: 2
    Last Post: Apr 15th, 2005, 12:37 PM
  5. Spring, JSF, Hibernate & Lazy Collections
    By e.medina.m in forum Data
    Replies: 3
    Last Post: Mar 9th, 2005, 03:28 AM

Posting Permissions

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