Versions:
Hibernate 3.2.2 ga
Database: Oracle 8.1.7
JDK: 1.5
I have two domain objects (one-to-many), BusinessRefence and BusinessReferenceValues that I want to load with one Criteria query (below). When I run the query, I get the correct set of BusinessReference domain objects. However, when I then attempt to load the BusinessReferenceValues (via businessRefence.getBusinessReferenceValues()), Hibernate generates extra queries to load the BusinessReferenceValue's (one query per BusinessReferenceValue) even though I have fetch="join" in the mapping. Using fetch="subselect" minimizes the number of extra queries, but why does Hibernate even need these extra queries? Shouldn't the first query provide enough information to hydrate both sides of the one-to-many.
CRITERIA QUERY:
Code:
Criteria query = getSession().createCriteria(BusinessReference.class);
query.createAlias("businessReferenceValues", "businessReferenceValue", Criteria.INNER_JOIN);
query.createAlias("businessReference.fleetStructure", "structure", Criteria.INNER_JOIN);
query.createAlias("structure.structureAccessLabel", "structureAccessLabel", Criteria.INNER_JOIN);
query.add( Subqueries.propertyEq("structure.structureId", createStructureSubQuery(corpFleet)));
query.add(Restrictions.eqProperty("structureAccessLabel.driverAccessLabel", "businessReferenceValue.key.label"));
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
GENERATED SQL:
Code:
select
---
from
reference_list this_,
INDIVIDUAL individual6_,
INDIVIDUAL_INFO individual7_,
bus_ref_list businessre1_,
STRUCTURE structure3_,
STRUCTURE_ACCESS_LABEL structurea4_,
bus_ref_access_values businessre2_
where
this_.reference_id=individual6_.REFERENCE_ID(+)
and individual6_.INDIVIDUAL_ID=individual7_.INDIVIDUAL_ID(+)
and this_.reference_id=businessre1_.reference_id
and businessre1_.structure_id=structure3_.structure_id
and structure3_.structure_id=structurea4_.structure_id
and businessre1_.bus_ref_id=businessre2_.bus_ref_id
and structure3_.structure_id = (
select
this0__.structure_id as y0_
from
STRUCTURE this0__
where
this0__.corp_code=?
and this0__.bus_code=?
and this0__.is_bus_str_element=?
)
and structurea4_.driver_access_label=businessre2_.bus_ref_access_label
(MANY OF THESE)
select
---
from
bus_ref_access_values businessre0_
where
businessre0_.bus_ref_id=?
MAPPINGS:
Code:
<hibernate-mapping>
<class name="com.ge.comfin.fleet.customerpersonsync.domain.cdb.reference.BusinessReference" table="bus_ref_list">
<id name="id" column="bus_ref_id" type="long"/>
<property name="effStartDate" column="bus_ref_start_date" type="date"/>
<property name="effEndDate" column="bus_ref_end_date" type="date"/>
<property name="modifyUserId" column="MODIFY_USERID" type="string" />
<property name="modifyDateTime" column="MODIFY_DATE_TIME" type="timestamp" />
<!-- Define one-to-one Relationships -->
<!-- Define the many-to-one relationships -->
<many-to-one name="fleetStructure" class="com.ge.comfin.fleet.customerpersonsync.domain.cdb.structure.Structure">
<column name="structure_id"/>
</many-to-one>
<many-to-one name="reference" class="com.ge.comfin.fleet.customerpersonsync.domain.cdb.reference.Reference" column="reference_id"/>
<!-- Define the one-to-many relationships (Set preferred)-->
<set name="businessReferenceValues" fetch="join">
<key column="bus_ref_id"/>
<one-to-many class="com.ge.comfin.fleet.customerpersonsync.domain.cdb.reference.BusinessReferenceValue"/>
</set>
</class>
</hibernate-mapping>
Code:
<hibernate-mapping>
<class name="com.ge.comfin.fleet.customerpersonsync.domain.cdb.reference.BusinessReferenceValue" table="bus_ref_access_values">
<composite-id name="key" class="com.ge.comfin.fleet.customerpersonsync.domain.cdb.reference.key.BusinessReferenceValueKey">
<key-property name="businessReferenceId" column="bus_ref_id" type="long"/>
<key-property name="label" column="bus_ref_access_label" type="string"/>
<key-property name="effStartDate" column="bus_ref_access_eff_date" type="date"/>
</composite-id>
<property name="value" column="bus_ref_access_value" type="string"/>
<property name="effEndDate" column="bus_ref_access_end_date" type="date"/>
<property name="modifyUserId" column="MODIFY_USERID" type="string" />
<property name="modifyDateTime" column="MODIFY_DATE_TIME" type="timestamp" />
</class>
</hibernate-mapping>