[Running Hibernate 3.3.1 ]
I am working on an app, I fetch a list of ItemPosts using a Dao, meaning a collection is returned. The challenge now is the collection returned contains an initialized item property. i.e The ItemPost list contains ItemPosts whose item property have been initialized. but When i try access the Item property of each ItemPost in the view layer another select is executed
Code:
@Transactional(readOnly = true)
public List<ItemPost> getAll() {
Session session = getSession();
Transaction tx = null;
List<ItemPost> itemPosts = null;
try {
tx = session.beginTransaction();
Query query = session.createQuery("from ItemPost itemPost inner join fetch itemPost.item " +
" where itemPost.expiryDate > :expiryDate order by itemPost.datePosted desc");
query.setParameter("expiryDate", Calendar.getInstance());
itemPosts = query.setCacheable(true).setCacheMode(CacheMode.NORMAL).list();
tx.commit();
// System.out.println("No of posts : "+itemPosts.size());
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return itemPosts;
}
My Mappings:
Code:
<hibernate-mapping package="com.pmega.easybuy.domain" >
<class name="ItemPost" table="item_posts">
<cache usage="read-write" />
<id name="postId" type="string" column="post_id" length="15">
<generator class="assigned" />
</id>
<property name="itemPostEnabled" type="boolean"
column="post_enabled" not-null="true" />
<property name="reactivateCount" type="integer"
column="reactivate_count" />
<property name="datePosted" type="calendar">
<column name="date_posted" not-null="true" />
</property>
<property name="expiryDate" type="calendar" >
<column name="date_expired" not-null="true" />
</property>
<property name="posterUsername" type="string" column="username" not-null="true" />
<many-to-one name="item" column="item_id" unique="true" cascade="delete"
not-null="true" class="Item" update="false" >
</many-to-one>
<set name="comments" table="post_comments" cascade="delete">
<cache usage="read-write"/>
<key column="post_id" />
<many-to-many column="comment_id" unique="true"
class="Comment" />
</set>
</class>
</hibernate-mapping>
Item Mapping
<hibernate-mapping package="com.pmega.easybuy.domain" >
<class name="Item" table="items" dynamic-update="true" >
<cache usage="read-write" />
<id name="itemId" type="string" column="item_id" length="15">
<generator class="assigned" />
</id>
<!-- <property name="categoryId" type="string" column="category_id" not-null="true"/> -->
<many-to-one name="category" column="category_id"
not-null="true" cascade="none" />
<property name="name" type="string" column="name"
not-null="true" />
<property name="priceNegotiable" type="string"
column="price_negotiable" not-null="true" />
<!-- <property name="quantity" type="integer" not-null="true" column="quantity"/> -->
<property name="price" type="double" column="price"
not-null="true" />
<property name="description" type="string" column="description"
not-null="true" />
<property name="itemDetails" type="string"
column="item_details" />
<property name="state" type="string" column="state" />
<component name="contactDetail" class="ContactDetail">
<property name="contactPhoneNumber" type="string"
column="contact_phoneno" />
<property name="contactEmail" column="contact_email" />
<property name="contactName" column="contact_name" />
<!-- <property name="contactAddress" column="contact_address"/> -->
</component>
</class>
</hibernate-mapping>
Code:
Hibernate: select itempost0_.post_id as post1_2_0_, item1_.item_id as item1_1_1_, itempost0_.post_enabled as post2_2_0_, itempost0_.reactivate_count as reactivate3_2_0_, itempost0_.date_posted as date4_2_0_, itempost0_.date_expired as date5_2_0_, itempost0_.username as username2_0_, itempost0_.item_id as item7_2_0_, item1_.category_id as category2_1_1_, item1_.name as name1_1_, item1_.price_negotiable as price4_1_1_, item1_.price as price1_1_, item1_.description as descript6_1_1_, item1_.item_details as item7_1_1_, item1_.state as state1_1_, item1_.contact_phoneno as contact9_1_1_, item1_.contact_email as contact10_1_1_, item1_.contact_name as contact11_1_1_ from item_posts itempost0_ inner join items item1_ on itempost0_.item_id=item1_.item_id where itempost0_.date_expired>? order by itempost0_.date_posted desc
Hibernate: select itempost0_.post_id as post1_2_0_, item1_.item_id as item1_1_1_, itempost0_.post_enabled as post2_2_0_, itempost0_.reactivate_count as reactivate3_2_0_, itempost0_.date_posted as date4_2_0_, itempost0_.date_expired as date5_2_0_, itempost0_.username as username2_0_, itempost0_.item_id as item7_2_0_, item1_.category_id as category2_1_1_, item1_.name as name1_1_, item1_.price_negotiable as price4_1_1_, item1_.price as price1_1_, item1_.description as descript6_1_1_, item1_.item_details as item7_1_1_, item1_.state as state1_1_, item1_.contact_phoneno as contact9_1_1_, item1_.contact_email as contact10_1_1_, item1_.contact_name as contact11_1_1_ from item_posts itempost0_ inner join items item1_ on itempost0_.item_id=item1_.item_id where itempost0_.date_expired>? order by itempost0_.date_posted desc
If the list is empty d Controller method handling request appears to execute just once. But if not empty and the item property is being accessed the Controller method handling d request is executed again. I wonder if dis shld be d behavior as the Item of each ItemPost have been initialized when d first query was executed, using an inner join so why d querying again just to serve one request. Double select querying takes place everytime the view displaying ItemPosts list is accessed. I hope I av bin explicit as possible for any body with a cue to help answer mi. I have posted dis bcos I feel d double select queryin wld draw a performance cost for a sys we are hoping to put into production. Thot d essence of the inner join was to eliminate double select querying?