I have the following design.
The table ap_step has a many to many relationship with table technology which is resolved with the join table ap_step_technology.
The table ap_step also has a one-to-one relation with table ap_detail_level
The table ap_step also has a one-to-one relation with table ap_step_category
In my application, I want to be able to retrieve steps based on some technologyId and I have accomplished this with the followin two methods:
List steps =
session.createCriteria(ApStepVO.class)
.setFetchMode("detail", FetchMode.LAZY)
.createAlias("technologies", "techs")
.add(Expression.eq("techs.technologyId", new Integer(techId)))
.list();
OR
List steps = session.getNamedQuery("findStepsByTechnologyId")
.setInteger("techId", techId)
.list();
As you will notice when using Criteria, I set the fetch mode for detail as lazy. But what ends up happening is that hibernate still queries the ap_detail_level table. In total hibernate does 7 queries for something that should only do one query. Here are the queries:
Hibernate: select this.ap_step_id as ap_step_id2_, this.ap_step as ap_step2_, this.ap_detail_level_id as ap_detai3_2_, this.ap_step_category_id as ap_step_4_2_, technologi1_.tech_id as tech_id__, technologi1_.ap_step_id as ap_step_id__, techs.tech_id as tech_id0_, techs.technology as technology0_, techs.description as descript3_0_, techs.ap_type_id as ap_type_id0_, aptypevo3_.ap_type_id as ap_type_id1_, aptypevo3_.ap_type as ap_type1_, aptypevo3_.description as descript3_1_ from ap_step this inner join ap_step_technology technologi1_ on this.ap_step_id=technologi1_.ap_step_id inner join technology techs on technologi1_.tech_id=techs.tech_id left outer join ap_type aptypevo3_ on techs.ap_type_id=aptypevo3_.ap_type_id where techs.tech_id=?
Hibernate: select apdetaille0_.level_id as level_id0_, apdetaille0_.level as level0_ from ap_detail_level apdetaille0_ where apdetaille0_.level_id=?
Hibernate: select apstepcate0_.ap_step_category_id as ap_step_1_0_, apstepcate0_.category as category0_, apstepcate0_.ap_category_desc as ap_categ3_0_ from ap_step_category apstepcate0_ where apstepcate0_.ap_step_category_id=?
Hibernate: select technologi0_.tech_id as tech_id__, technologi0_.ap_step_id as ap_step_id__, technology1_.tech_id as tech_id0_, technology1_.technology as technology0_, technology1_.description as descript3_0_, technology1_.ap_type_id as ap_type_id0_, aptypevo2_.ap_type_id as ap_type_id1_, aptypevo2_.ap_type as ap_type1_, aptypevo2_.description as descript3_1_ from ap_step_technology technologi0_ inner join technology technology1_ on technologi0_.tech_id=technology1_.tech_id left outer join ap_type aptypevo2_ on technology1_.ap_type_id=aptypevo2_.ap_type_id where technologi0_.ap_step_id=?
Hibernate: select steps0_.ap_step_id as ap_step_id__, steps0_.tech_id as tech_id__, apstepvo1_.ap_step_id as ap_step_id0_, apstepvo1_.ap_step as ap_step0_, apstepvo1_.ap_detail_level_id as ap_detai3_0_, apstepvo1_.ap_step_category_id as ap_step_4_0_ from ap_step_technology steps0_ inner join ap_step apstepvo1_ on steps0_.ap_step_id=apstepvo1_.ap_step_id where steps0_.tech_id=?
Hibernate: select steps0_.ap_step_id as ap_step_id__, steps0_.tech_id as tech_id__, apstepvo1_.ap_step_id as ap_step_id0_, apstepvo1_.ap_step as ap_step0_, apstepvo1_.ap_detail_level_id as ap_detai3_0_, apstepvo1_.ap_step_category_id as ap_step_4_0_ from ap_step_technology steps0_ inner join ap_step apstepvo1_ on steps0_.ap_step_id=apstepvo1_.ap_step_id where steps0_.tech_id=?
Hibernate: select steps0_.ap_step_id as ap_step_id__, steps0_.tech_id as tech_id__, apstepvo1_.ap_step_id as ap_step_id0_, apstepvo1_.ap_step as ap_step0_, apstepvo1_.ap_detail_level_id as ap_detai3_0_, apstepvo1_.ap_step_category_id as ap_step_4_0_ from ap_step_technology steps0_ inner join ap_step apstepvo1_ on steps0_.ap_step_id=apstepvo1_.ap_step_id where steps0_.tech_id=?
and here are my mappings:
<?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.securance.vo.ApStepVO"
table="ap_step"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="stepId"
column="ap_step_id"
type="int"
>
<generator class="native">
</generator>
</id>
<property
name="step"
type="java.lang.String"
update="true"
insert="true"
column="ap_step"
/>
<many-to-one
name="detail"
class="com.securance.vo.ApDetailLevelVO"
cascade="none"
outer-join="false"
update="true"
insert="true"
column="ap_detail_level_id"
/>
<many-to-one
name="stepCategory"
class="com.securance.vo.ApStepCategoryVO"
cascade="none"
outer-join="false"
update="true"
insert="true"
column="ap_step_category_id"
unique="true"
/>
<set
name="clientAssistance"
table="ap_step_client_assistance"
lazy="true"
inverse="false"
cascade="all"
sort="unsorted"
>
<key
column="ap_step_id"
/>
<many-to-many
class="com.securance.vo.ClientRequestAssistanceVO"
column="client_assist_id"
outer-join="auto"
/>
</set>
<set
name="technologies"
table="ap_step_technology"
lazy="false"
inverse="false"
cascade="none"
sort="unsorted"
>
<key
column="ap_step_id"
/>
<many-to-many
class="com.securance.vo.TechnologyVO"
column="tech_id"
outer-join="auto"
/>
</set>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-ApStepVO.xml
containing the additional properties and place it in your merge dir.
-->
</class>
<query name="findStepsByTechnologyId"><![CDATA[
select step from ApStepVO step join step.technologies techs where techs.technologyId = :techId
]]></query>
</hibernate-mapping>
<?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.securance.vo.ApDetailLevelVO"
table="ap_detail_level"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="levelId"
column="level_id"
type="int"
>
<generator class="native">
</generator>
</id>
<property
name="levelDesc"
type="java.lang.String"
update="true"
insert="true"
column="level"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-ApDetailLevelVO.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
<?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.securance.vo.ApStepCategoryVO"
table="ap_step_category"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="categoryId"
column="ap_step_category_id"
type="int"
>
<generator class="native">
</generator>
</id>
<property
name="category"
type="java.lang.String"
update="true"
insert="true"
column="category"
/>
<property
name="categoryDesc"
type="java.lang.String"
update="true"
insert="true"
column="ap_category_desc"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-ApStepCategoryVO.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
<?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.securance.vo.TechnologyVO"
table="technology"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="technologyId"
column="tech_id"
type="int"
>
<generator class="native">
</generator>
</id>
<property
name="technologyName"
type="java.lang.String"
update="true"
insert="true"
column="technology"
/>
<property
name="description"
type="java.lang.String"
update="true"
insert="true"
column="description"
/>
<many-to-one
name="apType"
class="com.securance.vo.ApTypeVO"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="ap_type_id"
/>
<set
name="steps"
table="ap_step_technology"
lazy="false"
inverse="true"
cascade="none"
sort="unsorted"
>
<key
column="tech_id"
/>
<many-to-many
class="com.securance.vo.ApStepVO"
column="ap_step_id"
outer-join="auto"
/>
</set>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-TechnologyVO.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
I've read the sample chapters of the book and gone through the archives, but I can't seem to find the solution to this. Maybe I am not using the right search terms.
Can anyone tell me what I am doing wrong. This is a major performance penalty that I want/need to avoid.
Thanks
|