0

I have a bunch of Hibernate mapped objects in my Spring MVC app. Default seems to be lazy loading for nested objects with relations. I realized this by getting a lot of errors in my JSP when accessing e.g. a list of children objects.

So I implemented a second method to get a list of objects with all children initliazed. I was wondering if someone could give me some feedback if this was the way to go or not?

This is my code in my DAO implementation that works:

public List<Address> getTripListFullyInitliazed() {

    HibernateTemplate template = getHibernateTemplate();

    List<Address> addresses = template.loadAll(Address.class);
    for (Address address : address) {
        template.initialize(address.getChildren());
    }
    return addresses;   
}

Can someone please tell me if this ok to do or if I should change something?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Czar
  • 356
  • 1
  • 4
  • 21

2 Answers2

3

I think a more elegant approach would be to use HQL JOIN FETCH clause, since it minimizes the number of SQL queries issued, as well as makes your code more clear:

public List<Address> getTripListFullyInitliazed() {
    return getHibernateTemplate().find(
        "from Address a left join fetch a.children");
}

See also:

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • Hm... I have to read some documentation on that as I don't understand how I am supposed to use this e.g. in the code above. But thanks for the hint. – Czar Jan 04 '11 at 08:22
  • 1
    @Czar: Code updated. This query instruct Hibernate to return entities with fully initialized `children` collections. – axtavt Jan 04 '11 at 12:32
  • THX. Are you supposed to really use HQl when there are those standard methods as well? – Czar Jan 04 '11 at 15:37
  • @Czar: I think it's important to pass your intentions to Hibernate in order to generate efficient SQL queries. Note that in this particular case, if you actually need all addresses with children, my approach fetches all data in one SQL query, whereas your original approach and `OpenSessionInViewFilter` approach suffers from [N + 1 problem](http://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem). – axtavt Jan 04 '11 at 16:06
  • @axtavt: Thanks for clarification. One more thing: if, say, I wanted to limit the list of fetched trips based on the logged in user ID, I guess I will HAVE to use HQL? I am asking becasue this will be my next step in development... – Czar Jan 04 '11 at 16:28
  • 1
    @Czar: Yes, it's the simpliest approach, although Hibernate has some advanced features: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/filters.html – axtavt Jan 04 '11 at 18:03
  • I have a question regarding the solution above: is it possible to return a multidimentional list as I guess this will return "duplicates" addresses if there exists several children for each address? – jorgen Jul 08 '11 at 12:28
2

I think the standard solution for this problem is to use OpenSessionInViewFilter:

Servlet 2.3 Filter that binds a Hibernate Session to the thread for the entire processing of the request. Intended for the "Open Session in View" pattern, i.e. to allow for lazy loading in web views despite the original transactions already being completed.

This filter makes Hibernate Sessions available via the current thread, which will be autodetected by transaction managers. It is suitable for service layer transactions via HibernateTransactionManager or JtaTransactionManager as well as for non-transactional execution (if configured appropriately).

Community
  • 1
  • 1
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588