In this recipe, we'll show you how to use HQL queries to eager load the child collections of our query results.
EagerLoadingWithHql
in the project.Recipe
to the folder:using NH4CookbookHelpers.Queries; using NH4CookbookHelpers.Queries.Model; using NHibernate; namespace QueryRecipes.EagerLoadingWithHql { public class Recipe : QueryRecipe { protected override void Run(ISession session) { var book = session.CreateQuery(@" from Book b left join fetch b.Publisher") .UniqueResult<Book>(); Show("Book:", book); var movies = session.CreateQuery(@" from Movie m left join fetch m.Actors") .SetResultTransformer( Transformers.DistinctRootEntity) .List<Movie>(); Show("Movies:", movies); } } }
EagerLoadingWithHql
recipe.For a detailed explanation of the eager loading mechanism, see the Eager loading with LINQ recipe. Take special note of the caveats mentioned in the There's more… section.
Eager loading in HQL is accomplished by adding the fetch
qualifier to a join
. In the recipe, we have used a left join
, since we want the root entity, even when there are no child entities; however, fetch
works equally well with standard (inner) joins
.
It might be tempting to add an alias to the fetched join and perhaps use it in a where
clause:
left join fetch m.Actors a where a.Actor=:name
That is strongly discouraged though, since the where clause now acts on the same join as the fetch. Not only does that limit the fetched collection itself, so that we end up with Movie
instances having invalid Actors
collections. It also effectively turns the left join
into an inner join
. If the query requires a filter on an ActorRole
property, use an extra separate join
or a subquery instead.
There is one scenario where an alias on the fetch join is needed, and that is if we want to eager load even deeper:
left join fetch m.Actors a left join fetch a.BookAboutTheRole
Just as with the Criteria
and QueryOver
queries, we need to process the results using the call to SetResultTransformer(Transformers.DistinctRootEntity)
. If we don't, we may end up with more movies in the list than we expected.
18.225.57.126