This is the mapping of my Category class:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<class
name="com.nmt.iws.entity.generated.Category"
table="category"
dynamic-update="true"
>
<id
name="id"
type="long"
>
<generator class="native" />
</id>
<property
name="name"
type="java.lang.String">
<column name="name"
not-null="true"
length="40"
index="parent_store_name_index"
unique-key="parent_store_name_key" />
</property>
<property name="visible" column="isvisible" not-null="true" type="boolean"/>
<many-to-one name="parent"
class="com.nmt.iws.entity.generated.Category" cascade="none"
outer-join="true"
>
<column name="parentid"
unique-key="parent_store_name_key"
index="parent_store_name_idx"
not-null="false"/>
</many-to-one>
<!-- bi-directional many-to-one association to Store -->
<many-to-one
name="store"
class="com.nmt.iws.entity.generated.Store"
outer-join = "false"
>
<meta attribute="finder">findByStore</meta>
<column name="storeid"
unique-key="parent_store_name_key"
index="parent_store_name_idx"
not-null="true"
/>
</many-to-one>
<set
name="children"
lazy="false"
inverse="true"
outer-join="true"
>
<key>
<column name="parentid" />
</key>
<one-to-many
class="com.nmt.iws.entity.generated.Category"
/>
</set>
</class>
</hibernate-mapping>
In brief: it has a recursive parent child one-to-many relationship.
I need to perform queries like:
Code:
select cat from Category as cat where cat.parent.id = :my_id
I want the query to eager fetch the children, recursively, in order to fetch the whole tree in one big but fast select.
I tried with
Query(session, "from Category as category left join fetch category.children where category.parent.id = :my_id") and no luck.
I tried with
List cats = session.createCriteria(Category.class)
.createCriteria("parent")
.setFetchMode("children", FetchMode.EAGER)
.add( Expression.eq("id", new Long(parentId)))
.list();
return cats;
and no luck.
I always obtain something like:
Quote:
3929 Query select category0_.id as id2_, category0_.name as name2_, category0_.isvisible as isvisible2_, category0_.storeid as storeid2_, category0_.parentid as parentid2_, category1_.id as id0_, category1_.name as name0_, category1_.isvisible as isvisible0_, category1_.storeid as storeid0_, category1_.parentid as parentid0_, children2_.id as id__, children2_.parentid as parentid__, children2_.id as id1_, children2_.name as name1_, children2_.isvisible as isvisible1_, children2_.storeid as storeid1_, children2_.parentid as parentid1_ from category category0_ left outer join category category1_ on category0_.parentid=category1_.id left outer join category children2_ on category1_.id=children2_.parentid where category0_.id=4104
3929 Query select children0_.id as id__, children0_.parentid as parentid__, children0_.id as id0_, children0_.name as name0_, children0_.isvisible as isvisible0_, children0_.storeid as storeid0_, children0_.parentid as parentid0_ from category children0_ where children0_.parentid=6912
3929 Query select children0_.id as id__, children0_.parentid as parentid__, children0_.id as id0_, children0_.name as name0_, children0_.isvisible as isvisible0_, children0_.storeid as storeid0_, children0_.parentid as parentid0_ from category children0_ where children0_.parentid=6919
3929 Query select children0_.id as id__, children0_.parentid as parentid__, children0_.id as id0_, children0_.name as name0_, children0_.isvisible as isvisible0_, children0_.storeid as storeid0_, children0_.parentid as parentid0_ from category children0_ where children0_.parentid=6927
3929 Query select children0_.id as id__, children0_.parentid as parentid__, children0_.id as id0_, children0_.name as name0_, children0_.isvisible as isvisible0_, children0_.storeid as storeid0_, children0_.parentid as parentid0_ from category children0_ where children0_.parentid=6924
3929 Query select children0_.id as id__, children0_.parentid as parentid__, children0_.id as id0_, children0_.name as name0_, children0_.isvisible as isvisible0_, children0_.storeid as storeid0_, children0_.parentid as parentid0_ from category children0_ where children0_.parentid=6926
Some extracts from the hibernate log
Quote:
2004-04-02 10:15:56,063 INFO [net.sf.hibernate.cfg.Environment] - Hibernate 2.1 final
2004-04-02 10:15:56,064 INFO [net.sf.hibernate.cfg.Environment] - hibernate.properties not found
2004-04-02 10:15:56,066 INFO [net.sf.hibernate.cfg.Environment] - using CGLIB reflection optimizer
2004-04-02 10:15:57,378 INFO [net.sf.hibernate.dialect.Dialect] - Using dialect: net.sf.hibernate.dialect.MySQLDialect
2004-04-02 10:15:57,378 INFO [net.sf.hibernate.cfg.SettingsFactory] - Use outer join fetching: true
2004-04-02 10:19:07,154 DEBUG [net.sf.hibernate.impl.SessionImpl] - find: from Category as category left join fetch category.children where category.parent.id = :my_id
2004-04-02 10:19:07,154 DEBUG [net.sf.hibernate.engine.QueryParameters] - named parameters: {my_id=4103}
2004-04-02 10:19:07,154 DEBUG [net.sf.hibernate.hql.QueryTranslator] - compiling query
2004-04-02 10:19:07,163 DEBUG [net.sf.hibernate.cache.QueryCache] - checking cached query results in region: net.sf.hibernate.cache.QueryCache
2004-04-02 10:19:07,163 DEBUG [net.sf.ehcache.hibernate.Plugin] - key: net.sf.hibernate.cache.QueryKey@fed522aa
2004-04-02 10:19:07,164 DEBUG [net.sf.ehcache.store.MemoryStore] - net.sf.hibernate.cache.QueryCacheCache: MemoryStore miss for net.sf.hibernate.cache.QueryKey@fed522aa
2004-04-02 10:19:07,164 DEBUG [net.sf.ehcache.Cache] - net.sf.hibernate.cache.QueryCache cache - Miss
2004-04-02 10:19:07,164 DEBUG [net.sf.ehcache.hibernate.Plugin] - Element for net.sf.hibernate.cache.QueryKey@fed522aa is null
2004-04-02 10:19:07,164 DEBUG [net.sf.hibernate.cache.QueryCache] - query results were not found in cache
2004-04-02 10:19:07,164 DEBUG [net.sf.hibernate.hql.QueryTranslator] - HQL: from com.nmt.iws.entity.generated.Category as category left join fetch category.children where category.parent.id = :my_id
2004-04-02 10:19:07,164 DEBUG [net.sf.hibernate.hql.QueryTranslator] - SQL: select category0_.id as id0_, children1_.id as id1_, category0_.name as name0_, category0_.isvisible as isvisible0_, category0_.storeid as storeid0_, category0_.parentid as parentid0_, children1_.name as name1_, children1_.isvisible as isvisible1_, children1_.storeid as storeid1_, children1_.parentid as parentid1_, children1_.id as id__, children1_.parentid as parentid__ from category category0_ left outer join category children1_ on category0_.id=children1_.parentid where (category0_.parentid=? )
2004-04-02 10:19:07,164 DEBUG [net.sf.hibernate.impl.BatcherImpl] - about to open: 0 open PreparedStatements, 0 open ResultSets
2004-04-02 10:19:07,164 DEBUG [net.sf.hibernate.impl.BatcherImpl] - prepared statement get: select category0_.id as id0_, children1_.id as id1_, category0_.name as name0_, category0_.isvisible as isvisible0_, category0_.storeid as storeid0_, category0_.parentid as parentid0_, children1_.name as name1_, children1_.isvisible as isvisible1_, children1_.storeid as storeid1_, children1_.parentid as parentid1_, children1_.id as id__, children1_.parentid as parentid__ from category category0_ left outer join category children1_ on category0_.id=children1_.parentid where (category0_.parentid=? )
The query is extemely poor in performance.
Do you have any ideas?