Hi,
I have a simple Parent child relationship. The mappings are as follows:
Parent.hbm.xmlCode:
<hibernate-mapping>
<class name="eg.Parent" table="parent">
<id name="id" column="id" type="integer" unsaved-value="null" >
<generator class="native"/>
</id>
<property name="name" not-null="true" column="name" />
<set name="children" cascade="all" inverse="true" outer-join="true">
<key column="parent_id"/>
<one-to-many class="eg.Child" />
</set>
</class>
</hibernate-mapping>
and
Child.hbm.xmlCode:
<class name="eg.Child" table="child">
<id name="id" column="id" type="integer" unsaved-value="null" >
<generator class="native"/>
</id>
<property name="name" not-null="true" column="name" />
<many-to-one name="parent" class="eg.Parent" column="parent_id" not-null="true" outer-join="true" />
</class>
</hibernate-mapping>
As you can see, the set is mapped with outer-join=true. This is a feature that I want to take advantange of.
I also have the following properties set in my
hibernate.cfg.xml file:
Code:
<property name="use_outer_join">true</property>
<property name="max_fetch_depth">3</property>
When I do the a simple load on the Parent, the outer join fetching works. i.e
Code:
Parent parent = (Parent)session.load(Parent.class, id);
Hibernate: select parent0_.id as id1_, parent0_.name as name1_, children1_.id as id__, children1_.parent_id as parent_id__, children1_.id as id0_, children1_.name as name0_, children1_.parent_id as parent_id0_ from parent parent0_ left outer join child children1_ on parent0_.id=children1_.parent_id where parent0_.id=?
However when I do a find, I get the following
Code:
List parents = session.find("from Parent p");
(or)
List parents = session.createQuery("from Parent p").list();
Hibernate: select parent0_.id as id, parent0_.name as name from parent parent0_
Hibernate: select children0_.id as id__, children0_.parent_id as parent_id__, children0_.id as id0_, children0_.name as name0_, children0_.parent_id as parent_id0_ from child children0_ where children0_.parent_id=?
i.e. Two queries with no outer join. To take advantage of the outer join facility I have to explicitly fetch the children. i.e.
Code:
List parents = session.find("from Parent p left join fetch p.children");
(or)
List parents = session.createQuery("from Parent p left join fetch p.children").list( );
.. which results in an outer join (as expected).
From the docs:
Quote:
Outer join fetching allows a graph of objects connected by many-to-one, one-to-many or one-to-one associations to be retrieved in a single SQL SELECT.
and goes on to say that:
Quote:
Only one collection may be fetched by outer join per SQL SELECT.
My question is:
Why - if you have mapped the collection as non-lazy (default) and outer-join="true" - is the collection not fetched in an outer-join manner when using find() and createQuery() if only one such 'outer-join' collection exists?