-->
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.  [ 3 posts ] 
Author Message
 Post subject: How to set a collection count without new property
PostPosted: Tue Jul 13, 2004 10:25 am 
Senior
Senior

Joined: Fri Jun 18, 2004 10:17 am
Posts: 140
I have a situation where I load a list of Schedule objects and each Schedule contains a Set of ScheduleUpdate objects. On my list page I only ever need to show the title, last created date and number of updates in the set belonging to the Schedule.

I was finding my list page quite slow as it is loading everything out including the ScheduleUpdate objects and sometimes just 1 Schedule has 25 of these.

Therefore I decided to restrict the amount brought back by Hibernate with a scalar query (shown in Java Code below).

I have however found a shortcoming of either Hibernate OR my knowledge ;) Basically my scalar query counts the updates available for the Schedule, but I have no property defined to store this numeric value into the Schedule object. I do not want to have to create another object which is just a stripped down version of Schedule and includes the count as that would be a little inefficient I think ... I would rather reuse a mainly nulled Schedule.

Can anyone suggest what the best thing to do might be for this situation? Do I need a stripped down Schedule? Do I need to add a new property to Schedule? Can I just add a new class member to Schedule WITHOUT adding it to the Schedule mapping file for persistence?

THANKS!

Hibernate
======

2.1

Mapping
=====

Code:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>

    <class name="com.qas.newmedia.intranet.iq.dto.schedules.Schedule" table="Schedules">

        <id name="id" type="int" column="schedule_id" unsaved-value="0">
           <generator class="identity" />
       </id>
            
        <property name="owner" column="owner" not-null="false" />
      <property name="associates" column="associates" not-null="false" />
      <property name="status" column="status" not-null="false" />
      <property name="title" column="title" not-null="true" />
      <property name="summary" column="summary" not-null="false" />
      <property name="description" column="description" not-null="false" />
      <property name="created" type="date" column="created" not-null="false" />
      <property name="lastUpdated" type="date" column="last_updated" not-null="false" />
      
      <set name="updates" order-by="created desc">
            <key column="schedule_id"/>
            <one-to-many class="com.qas.newmedia.intranet.iq.dto.schedules.ScheduleUpdate"/>
        </set>
      
      <set name="links" order-by="created desc">
            <key column="schedule_id"/>
            <one-to-many class="com.qas.newmedia.intranet.iq.dto.schedules.ScheduleLink"/>
        </set>
      
      <!--
        - Product Schedule
        -->
      
      <joined-subclass
         name="com.qas.newmedia.intranet.iq.dto.schedules.ProductSchedule"
         table="ProductSchedules">
         
           <key column="schedule_id" />
         
         <property name="developmentSignoff" type="date" column="development_signoff" not-null="false" />
         <property name="developmentSignoffFormat" column="development_signoff_format" not-null="false" />
         <property name="qatSignoff" type="date" column="qat_signoff" not-null="false" />
         <property name="qatSignoffFormat" column="qat_signoff_format" not-null="false" />
         <property name="launch" type="date" column="launch" not-null="false" />
         <property name="launchFormat" column="launch_format" not-null="false" />
       </joined-subclass>
      
      <!--
        - QA For Schedule
        -->      
      
      <joined-subclass
         name="com.qas.newmedia.intranet.iq.dto.schedules.QAForSchedule"
         table="QAForSchedules">
         
           <key column="schedule_id" />
         
         <property name="developmentSignoff" type="date" column="development_signoff" not-null="false" />
         <property name="developmentSignoffFormat" column="development_signoff_format" not-null="false" />
         <property name="qatSignoff" type="date" column="qat_signoff" not-null="false" />
         <property name="qatSignoffFormat" column="qat_signoff_format" not-null="false" />
         <property name="launch" type="date" column="launch" not-null="false" />
         <property name="launchFormat" column="launch_format" not-null="false" />
       </joined-subclass>            

      <!--
        - Data Acquisition Schedule
        -->

      <joined-subclass
         name="com.qas.newmedia.intranet.iq.dto.schedules.DataAcquisitionSchedule"
         table="DataAcquisitionSchedules">
         
           <key column="schedule_id" />
         
         <property name="productRelease" column="product_release" not-null="false" />
       </joined-subclass>
      
      <!--
        - Project Schedule
        -->      
      
      <joined-subclass
         name="com.qas.newmedia.intranet.iq.dto.schedules.ProjectSchedule"
         table="ProjectSchedules">
         
           <key column="schedule_id" />
         
         <property name="approval" type="date" column="approval" not-null="false" />
         <property name="targetCompletion" type="date" column="target_completion" not-null="false" />
       </joined-subclass>            

    </class>
   
   <class name="com.qas.newmedia.intranet.iq.dto.schedules.ScheduleUpdate" table="ScheduleUpdates">

        <id name="id" type="int" column="update_id" unsaved-value="null">
           <generator class="identity" />
       </id>

      <property name="created" type="date" not-null="true" />
      <property name="author" column="author" not-null="true" />
      <property name="comment" column="comment" type="text" length="4096" not-null="true" />
      <property name="internal" column="internal" type="boolean" />
         
   </class>
   
   <class name="com.qas.newmedia.intranet.iq.dto.schedules.ScheduleLink" table="ScheduleLinks">

        <id name="id" type="int" column="link_id" unsaved-value="null">
           <generator class="identity" />
       </id>

      <property name="created" type="date" not-null="true" />
      <property name="label" column="label" not-null="true" />
      <property name="link" column="link" not-null="true" />
         
   </class>   

</hibernate-mapping>



Java Code
=======

Code:

Session session = HibernateUtil.currentSession();
           Transaction tx = session.beginTransaction();
                       
            Iterator results = session.iterate(
               "select s.id, s.title, s.status, count(elements(s.updates)) " +
               "from " + type + " s group by s.id, s.title, s.status"
         );
                     
            while(results.hasNext()) {
                Object[] row = (Object[]) results.next();
                Schedule schedule = new Schedule();
                schedule.setId(((Integer) row[0]).intValue());
                schedule.setTitle((String) row[1]);
                schedule.setStatus((String) row[2]);
                //scheduleRow.setNumUpdates(((Integer) row[3]).intValue());
                list.add(schedule);
            }
           
            tx.commit();



Stack
====

N/A

DB
==

SQLServer 2000

Hibernate Log
=========

select productsch0_.schedule_id as x0_0_, productsch0__1_.title as x1_0_, productsch0__1_.status as x2_0_, count(updates1_.update_id) as x3_0_ from ProductSchedules productsch0_ inner join Schedules productsch0__1_ on productsch0_.schedule_id=productsch0__1_.schedule_id, ScheduleUpdates updates1_ where productsch0_.schedule_id=updates1_.schedule_id group by productsch0_.schedule_id , productsch0__1_.title , productsch0__1_.status
[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 13, 2004 10:31 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
One possibility would be to create a new object and to use the select new syntax:

Code:
select new StatusListItem(s.id, s.title, s.status, count(elements(s.updates))) from StatusItem s group by s.id, s.title, s.status


Another, IMHO nicer way would be to define the status collection as lazy, and use a collection filter to get the count:

Code:
StatusItem s = session.find("from StatusItem").get(0);
int updateCount = ( (Integer) s.createFilter( s.getUpdates(), "select count(*)" ).iterate().next() ).intValue();


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 13, 2004 10:43 am 
Senior
Senior

Joined: Fri Jun 18, 2004 10:17 am
Posts: 140
I need to send a List of Schedule objects to my UI so I can iterate over them nicely using JSTL or similar. Therefore each object in the List should ideally only have the properties I require including the count.

I tried out adding a new class member called numUpdates to the Schedule object and this modified version of my load method then works and it is noticeably faster. I do not add numUpdates as a property to my HBM. It also means only 1 HQL statement whereas I think your version does quite a few calls.

I don't think I understand your suggestions too well especially since I do not use an object called StatusListItem but I also cannot see how it is more efficient...

What do you think of what I have done with numUpdates?

Code:
public List load(String type, String orderBy, String orderDir)
      throws SchedulesException {
      
      List list = new ArrayList();;
       
        try {
           Session session = HibernateUtil.currentSession();
           Transaction tx = session.beginTransaction();
           
            Iterator results = session.iterate(
               "select s.id, s.title, s.status, s.lastUpdated, count(elements(s.updates)) " +
               "from " + type + " s " +
            "group by s.id, s.title, s.status, s.lastUpdated " +
               "order by " + orderBy + " " + orderDir
         );
                     
            while(results.hasNext()) {
                Object[] row = (Object[]) results.next();
               
                Schedule schedule = new Schedule();
                schedule.setId(((Integer) row[0]).intValue());
                schedule.setTitle((String) row[1]);
                schedule.setStatus((String) row[2]);
                schedule.setLastUpdated((Date) row[3]);
                schedule.setNumUpdates(((Integer) row[4]).intValue());
               
                list.add(schedule);
            }
           
            tx.commit();
        }
        catch (HibernateException hE) {
           throw new SchedulesException(hE.getMessage());
        }
       
        return list;

   }


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.