Eager fetching nested object with DetachedCriteria in Hibernate

seanhodges picture seanhodges · Nov 7, 2012 · Viewed 9.7k times · Source

I have to modify a large Hibernate DetachedCriteria query to fetch some additional associations.

My object graph resembles the structure below, I want to fetch the sales associated with each Car:

<class name="Showroom" table="showroom">
    ...
    <bag name="cars" lazy="false">
        <one-to-many class="Car" />
    </bag>
    ...
</class>

<class name="Car" table="car">
    ...
    <set name="sales" lazy="true">
        <one-to-many class="Sale" />
    </set>
    ...
</class>

What I want to do is something like:

DetachedCriteria criteria = DetachedCriteria.forClass(Showroom.class);
// ... Existing criteria query code ...
criteria.setFetchMode("cars.sales", FetchMode.JOIN);

But the associationPath argument in setFetchMode seems to ignore the dot notation and I get a LazyInitializationException:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: Car.sales, no session or session was closed

I've search around and so far found no examples or information. The Hibernate documentation does not provide examples on how to fetch nested associations, and the Javadoc for setFetchMode seems to suggest that my dot-notation approach should have worked...

Any help would be appreciated.

Answer

JB Nizet picture JB Nizet · Nov 16, 2012
DetachedCriteria dc = DetachedCriteria.forClass(ShowRoom.class, "showRoom");
criteria.setFetchMode("showRoom.cars", FetchMode.JOIN);
criteria.createAlias("showRoom.cars", "car", CriteriaSPecification.LEFT_JOIN);
criteria.setFetchMode("car.sales", FetchMode.JOIN);

You can't chain properties in a criteria query. And even in a HQL queries, cars.sales is invalid, since cars refers to a collection, and not to an instance of Car. A join is necessary to be able to refer to a Car in the collection of cars. That's what the createAlias() call does. The above is similar to

select showRoom from ShowRoom
left join fetch showRoom.cars car
left join fetch car.sales