1

I have for example, a DB with the following entity and relation structure:

[Person] has many [Skills], [Skills] has many [Actions]

In the .hbm.xml's, I assign one-to-many relations for person > skills, skills > actions.

In a query, I would like to be able to control when I query on Person, to eager load only the Skills. Currently, I seem to be stuck where i'm eager loading NOTHING, and generating a n+1 amount of queries to get a Person's Skills, or am generating an (n*n+1) amount of queries as it eagerly loads the entire Person > Skills > Actions collection hierarchy.

How would I limit it such that I can control when I do and do not want to load the third depth table? For context, I'd be able to live with always having Person > Skills collection initialized, ideally as a JOIN to prevent n+1 performance bottlenecks.

Eric
  • 1,953
  • 4
  • 24
  • 33
  • Can't you just set Actions to lazy-load on the Skills mapping? Calling skills.getActions() will cause Hib to fetch them when you need. Or am I misunderstanding your problem? – bvulaj Mar 30 '12 at 13:49

3 Answers3

0

This turned out to be pretty easy to control at runtime.

In my .hbm.xml's i continued to declare my association sets as lazy, (even extra lazy!).

In the HQL query, I query like:

Select distinct p from Person

left join fetch p.skills

the fetch keyword forces eager loading for that particular join.

Eric
  • 1,953
  • 4
  • 24
  • 33
0

I use the following practice:

I try to avoid child collections on objects, especially if a child collection could have a lot of entries. If I need to get the children, I use a query to get them.

If I do have child collections, I always set collections to be lazy loaded.

For 'querying', using the Criteria API, I have a class that creates the query, executes it and returns the result. As part of building the query, I use root.fetch(Person_.skills); where root is javax.persistence.criteria.Root<Person> to eagerly load the collections I want.

Craig Swing
  • 8,152
  • 2
  • 30
  • 43
  • I was thinking of going this route as well, and I probably will end up there. But I was hoping there would be a more direct way of telling Hibernate "Initialize the root object's collections, but not those collection's collections". In some dynamic way. My app drills down, so I only ever need access to the next-deep associations. – Eric Mar 30 '12 at 16:50
0

It's a little bit off-topic, but you might consider to use some implementation of Graph Database to maintain data of such level of complexity instead of RDBMS and Hiberante. See neo4j, the graph database , which allows to create nodes (in you case persons, skills) and relations between them (extends, knows). So you will be able to easily traversal a data at any level of deep.

adrift
  • 637
  • 2
  • 10
  • 34