-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: setFetchMode FetchMode.JOIN for multiple nested collections?
PostPosted: Wed Sep 07, 2011 6:10 am 
Beginner
Beginner

Joined: Wed Sep 30, 2009 5:29 am
Posts: 29
Hi all,

I'm attempting to optimize an application with some familiar object relationships, and I'm unsure if it's possible (or wise) to try to fetch a whole object graph in one SELECT. I've searched and found posts from 2004, 5 and 6, but nothing very recent. The documentation describes optimizing SELECTs using FetchMode.JOIN for single level relationships, but not multiple level relationships.

I found a forum post saying that Hibernate does support this kind of fetching, while NHibernate does not .. so, I believe there might be some tricks I don't know about Hibernate. I've spent the day investigating options, and also playing with the second level cache (ehcache), and reading lots of documentation. I'd appreciate some crticism of my approach.

So, here goes.

Say I have an entity model like this:

Code:
Classroom 1....* Person (OneToMany List<> with a JoinColumn)
Person 1....* Limbs (OneToMany List<>)
Person 1....* Doodads (OneToMany List<>)
Person 1....* Expectations (OneToMany List<> with a JoinTable)


So a Classroom will be associated with (OneToMany) many Person instances, and each Person instance will be associated with (OneToMany) collections of Limbs, Doodads, and Expectations. All these relationships use the default fetch strategy, LAZY.

I'd like to leave the default fetch strategy as LAZY, but when necessary, completely initialise a Classroom entity and all the related sub-entities in one Criteria query.

When selecting a Classroom I am doing:

Code:
Classroom c = (Classroom)session.createCriteria(Classroom.class)
    .add(Restrictions.eq("id", "something"))
    .setFetchMode("persons", FetchMode.JOIN)
    .setFetchMode("persons.limbs", FetchMode.JOIN)
    .setFetchMode("persons.doodads", FetchMode.JOIN)
    .setFetchMode("persons.expectations", FetchMode.JOIN)
    .uniqueResult();


So I expect to get back a single Classroom instance, with its collection of Person entities populated, and each Person should have its Limbs, Doodads and Expectations collections populated.

Is this sensible? Does it make sense to setFetchMode for "persons" and several collections of the "persons" relationship as I have done?

I don't believe a SQL SELECT statement, with a single result set, is suitable for this problem. In my real application the generated SQL seems basically OK, but I fear I'm basically misusing the concept of JOIN fetching by trying to fetch too many 'levels' of relationship in a single query.

My reason for asking is that I have an inner loop that wants to dump the entire object graph to a data structure (for return as JSON to a web UI):

Code:
Map<String, Object> resultMap = new HashMap<String, Object>();
MapUtils.classroomToMap(resultMap, c);
List<Map<String, Object>> personList = new ArrayList<Map<String, Object>>();
for (Person p : c.getPersons()) {
    Map<String, Object> personMap = new HashMap<String, Object>();
    MapUtils.personToMap(personMap, p);
    personLoad.add(personMap);
}
resultMap.put("personList", personList);


Without .setFetchMode() used at all, each person.getLimbs(), person.getExpectations() etc. calls result in a SELECT statement to the database, so the inner loop is inefficient. I'm trying to get all the database work done in as few calls as possible, to get the whole entity graph in memory before the for loop is entered, so no database hits are required during its traversal of the object graph.

Nick


Top
 Profile  
 
 Post subject: Re: setFetchMode FetchMode.JOIN for multiple nested collections?
PostPosted: Thu Sep 08, 2011 2:02 am 
Beginner
Beginner

Joined: Wed Sep 30, 2009 5:29 am
Posts: 29
I've now enabled ehcache and my collections and entities are being retrieved from the cache, which has greatly alleviated the need for this optimisation. I can just specify a fetch of one level when fetching a Classroom, and not worry about the accessing of Person collections causing further fetches, since the Person attributes are all coming from the second level cache.
Code:
Classroom c = (Classroom)session.createCriteria(Classroom.class)
    .add(Restrictions.eq("id", "something"))
    .setFetchMode("persons", FetchMode.JOIN)
    .uniqueResult();

Would be nice to get an answer to the original question, though :)


Top
 Profile  
 
 Post subject: Re: setFetchMode FetchMode.JOIN for multiple nested collections?
PostPosted: Sun Dec 11, 2011 1:02 pm 
Newbie

Joined: Sat Sep 10, 2011 10:22 pm
Posts: 8
I have the same question as Nick about nested collections and FetchMode.JOIN on a Criteria. Can one of the Hibernate gurus please answer or point us to the documentation / wiki that has the answer?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.