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]