-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: RESOLVED criteria with join and eager loading
PostPosted: Tue Sep 28, 2010 7:11 pm 
Beginner
Beginner

Joined: Fri Mar 11, 2005 7:46 am
Posts: 29
hi all - I am having problems figuring out if this is an issue or correct behaviour, and if it is correct behaviour, how to achieve desired result. I have 2 entities, ProductionOrder and Model. Each order has one model, model can have multiple orders against it.

Code:
<hibernate-mapping package="model.application">
    <class name="ProductionOrder" table="PO" lazy="false" batch-size="10">
        <composite-id name="key" class="ProductionOrderKey">
            <key-property name="orderNumber" column="POORDNO"/>
            <key-property name="headerDetail" column="POHD" />
            <key-property name="modelCode" column="POMDL" />
            <key-property name="type" column="POTYPE" />
            <key-property name="option" column="POOPT" />
            <key-property name="hesColour" column="POHESC" />
            <key-property name="trimColour" column="POTRMCOL" />
        </composite-id>
        <property name="orderedQuantity" type="big_decimal" column="POQTY" not-null="true"/>
        <property name="shippedQuantity" type="big_decimal" column="POSHQTY" not-null="true"/>
        <property name="deliveryYear" type="int" column="PODLVYR" not-null="true"/>
        <property name="deliveryMonth" type="int" column="PODLVMTH" not-null="true"/>
        <property name="deliveryDate" formula="PODLVYR || PODLVMTH"/>
        <many-to-one name="model" class="Model"
            fetch="join" lazy="false" not-found="ignore" insert="false" update="false">
            <column name="POMDL"/>
            <column name="POTYPE"/>
            <column name="POOPT"/>
            <column name="POHESC"/>           
        </many-to-one>
    </class>     
</hibernate-mapping>

<hibernate-mapping package="model.application">   
    <class name="Model" table="MM" lazy="false">
        <composite-id name="hmModel" class="InternationalVehicleModel">
            <key-property name="modelCode" column="MMMDL"/>
            <key-property name="type" column="MMTYPE" />
            <key-property name="option" column="MMOPT" />
            <key-property name="hesColour" column="MMHESC" />
        </composite-id>
        <component name="auhModel" lazy="false">
            <property name="modelCode" type="string" column="MMNMDL" not-null="true"/>
            <property name="doors" type="string" column="MMNDOOR" not-null="true"/>
            <property name="transmission" type="string" column="MMNTRAN" not-null="true"/>
            <property name="grade" type="string" column="MMNGRADE" not-null="true"/>
            <property name="colour" type="string" column="MMNCOL" not-null="true"/>
            <property name="year" type="string" column="MMNYEAR" not-null="true"/>
        </component>
    </class>   
</hibernate-mapping>


When I need to find an order, I use Criteria API and I would usually add some restrictions on model, eg. (you can ignore populateCriteria/populateStringCriteria - all they do is add Property.eq or Property.like to the criteria).

Code:
DetachedCriteria criteria = DetachedCriteria
                .forClass(ProductionOrder.class);
        criteria.createAlias("model", "model");
        criteria.setFetchMode("model", FetchMode.JOIN);
        populateCriteria(criteria, CriteriaOperation.LIKE, "key.orderNumber", "7%");
        populateCriteria(criteria, CriteriaOperation.EQUALS, "key.headerDetail", "1");
        populateCriteria(criteria, CriteriaOperation.BETWEEN, "deliveryDate",
                new String[] {startDate, endDate});
        populateStringCriteria(criteria, "model.auhModel.modelCode", model
                .getModelCode());
        populateStringCriteria(criteria, "model.auhModel.transmission", model
                .getTransmission());
        populateStringCriteria(criteria, "model.auhModel.doors", model.getDoors());
        populateStringCriteria(criteria, "model.auhModel.grade", model.getGrade());
        populateStringCriteria(criteria, "model.auhModel.colour", model.getColour());
        populateStringCriteria(criteria, "model.auhModel.year", model.getYear());       
        populateWarehouseCriteria(criteria, "warehouse", warehouse);


When I run this query - I see the generated SQL that has the join between order and model table - just what I need.

Code:
DEBUG [org.hibernate.SQL] - select this_.poordno as poordno5_1_, this_.pohd as pohd5_1_, this_.pomdl as pomdl5_1_, this_.potype as potype5_1_, this_.poopt as poopt5_1_, this_.pohesc as pohesc5_1_, this_.potrmcol as potrmcol5_1_, this_.powh as powh5_1_, this_.poqty as poqty5_1_, this_.poshqty as poshqty5_1_, this_.podlvyr as podlvyr5_1_, this_.podlvmth as podlvmth5_1_, this_.PODLVYR || this_.PODLVMTH as formula0_1_, model1_.mmmdl as mmmdl1_0_, model1_.mmtype as mmtype1_0_, model1_.mmopt as mmopt1_0_, model1_.mmhesc as mmhesc1_0_, model1_.mmnmdl as mmnmdl1_0_, model1_.mmndoor as mmndoor1_0_, model1_.mmntran as mmntran1_0_, model1_.mmngrade as mmngrade1_0_, model1_.mmncol as mmncol1_0_, model1_.mmnyear as mmnyear1_0_ from mpop this_ inner join mmmp model1_ on this_.pomdl=model1_.mmmdl and this_.potype=model1_.mmtype and this_.poopt=model1_.mmopt and this_.pohesc=model1_.mmhesc where this_.poordno like ? and this_.pohd=? and this_.PODLVYR || this_.PODLVMTH between ? and ? and model1_.mmnmdl=? and this_.powh=? order by this_.PODLVYR || this_.PODLVMTH asc


As you can see, the query has all the columns required to populate both ProductionOrder and Model - just what I need! But then comes the problem - when Hibernate hydrates entities (ProductionOrder and Model) - it runs another query to read only model table - and it runs this query for each row returned from the first query:

Code:
2010-09-28 13:30:36,791  DEBUG [org.hibernate.loader.Loader] - loading entity: [model.application.Model#component[modelCode,type,option,hesColour]{option=   , type=KQ  , hesColour=HC001  , modelCode=TSTMDL1  }]
2010-09-28 13:30:36,791  DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2010-09-28 13:30:36,791  DEBUG [org.hibernate.SQL] - select model0_.mmmdl as mmmdl1_0_, model0_.mmtype as mmtype1_0_, model0_.mmopt as mmopt1_0_, model0_.mmhesc as mmhesc1_0_, model0_.mmnmdl as mmnmdl1_0_, model0_.mmndoor as mmndoor1_0_, model0_.mmntran as mmntran1_0_, model0_.mmngrade as mmngrade1_0_, model0_.mmncol as mmncol1_0_, model0_.mmnyear as mmnyear1_0_ from mmmp model0_ where model0_.mmmdl=? and model0_.mmtype=? and model0_.mmopt=? and model0_.mmhesc=?
Hibernate: select model0_.mmmdl as mmmdl1_0_, model0_.mmtype as mmtype1_0_, model0_.mmopt as mmopt1_0_, model0_.mmhesc as mmhesc1_0_, model0_.mmnmdl as mmnmdl1_0_, model0_.mmndoor as mmndoor1_0_, model0_.mmntran as mmntran1_0_, model0_.mmngrade as mmngrade1_0_, model0_.mmncol as mmncol1_0_, model0_.mmnyear as mmnyear1_0_ from mmmp model0_ where model0_.mmmdl=? and model0_.mmtype=? and model0_.mmopt=? and model0_.mmhesc=?
2010-09-28 13:30:37,260  DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to open ResultSet (open ResultSets: 0, globally: 0)
2010-09-28 13:30:37,260  DEBUG [org.hibernate.loader.Loader] - result row: EntityKey[model.application.Model#component[modelCode,type,option,hesColour]{option=   , type=KQ  , hesColour=HC001  , modelCode=TSTMDL1  }]
2010-09-28 13:30:37,260  DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to close ResultSet (open ResultSets: 1, globally: 1)
2010-09-28 13:30:37,260  DEBUG [org.hibernate.jdbc.AbstractBatcher] - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2010-09-28 13:30:37,260  DEBUG [org.hibernate.engine.TwoPhaseLoad] - resolving associations for [model.application.Model#component[modelCode,type,option,hesColour]{option=   , type=KQ  , hesColour=HC001  , modelCode=TSTMDL1  }]
2010-09-28 13:30:37,260  DEBUG [org.hibernate.engine.TwoPhaseLoad] - done materializing entity [model.application.Model#component[modelCode,type,option,hesColour]{option=   , type=KQ  , hesColour=HC001  , modelCode=TSTMDL1  }]
2010-09-28 13:30:37,260  DEBUG [org.hibernate.loader.Loader] - done entity load
2010-09-28 13:30:37,260  DEBUG [org.hibernate.engine.TwoPhaseLoad] - done materializing entity [model.application.ProductionOrder#component[orderNumber,headerDetail,modelCode,type,option,hesColour,trimColour]{option=   , headerDetail=1, type=KQ  , trimColour=BK, orderNumber=760271400, hesColour=HC001  , modelCode=TSTMDL1  }]


Can hibernate gurus please advise if desired behaviour is possible at all? I mean - is it possible to use the values from the first query to populate both entities, not just entity keys and then go to database again to resolve associations? Any input appreciated - I tried different ways, HQL with fetch join, different ResultTransformers - it all goes to the TwoPhaseLoad mechanism - looks like it ignores anything but keys from the first result set and then it resolves entities by fetching corresponding row using the id it got from the initial resultset.


Last edited by kostaky on Wed Sep 29, 2010 9:20 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: RESOLVED criteria with join and eager loading
PostPosted: Wed Sep 29, 2010 9:20 pm 
Beginner
Beginner

Joined: Fri Mar 11, 2005 7:46 am
Posts: 29
The issue was in different length of CHAR columns on our DB2 for iSeries database. Once the lenght was matched, the entity was successfully resolved from Session cache.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.