-->
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: composite-id and bi-directional - children not loaded
PostPosted: Thu Jun 24, 2004 6:43 pm 
Newbie

Joined: Mon May 10, 2004 1:10 pm
Posts: 5
I searched and searched, re-read the docs (especially chapter 7.4), but I'm still at a loss as of what is happening. I am using Hibernate 2.1 and connecting to an Informix 7.31 database.

I have a ClubList (table name = listhdr) object that has a 1:M relationship with ListItem (table name = listdet). The PK of ClubList is a composite key consisting of listDay and listNumber. The PK of ListItem is a composite key consisting of listDay, listNumber, and itemSequence.

Based on the doc's recommendation, I created a ClubListPK class to encapsulate listDay and listNumber. I have also implemented equals() and hashCode() in each object.

Problem:I can successfully load a ClubList object (using session.load()), but the children are not loaded. The odd thing is that, based on the sql statements from Hibernate, it looks like they are being loaded. I put a debug statement in the ListItem.setItemSequence() method and I can see the correct sequences in the output. Also, it looks like I am getting a bunch of extra selects that I don't believe should be there.

Here are the abbreviated mappings:
Code:
<hibernate-mapping package="ccx.beans.cls">
   <class name="ClubList" table="listhdr">
      <composite-id name="key" class="ccx.beans.cls.ClubListPK">
         <key-property name="listDay" column="listday" type="ccx.dao.hibernate.TrimmedChar" />
         <key-property name="listNumber" column="listnum"/>
      </composite-id>
      <property name="clubCode" type="ccx.dao.hibernate.TrimmedChar" column="clubcode"/>
      <bag name="items" lazy="true" inverse="true" >
         <key>
            <column name="listday"/>
            <column name="listnum"/>
         </key>
         <one-to-many class="ListItem"/>
      </bag>
   </class>
</hibernate-mapping>

<hibernate-mapping package="ccx.beans.cls">
   <class name="ListItem" table="listdet">
      <composite-id unsaved-value="any">
         <key-many-to-one name="clubList" class="ccx.beans.cls.ClubList">
            <column name="listday"/>
            <column name="listnum"/>
         </key-many-to-one>
         <key-property name="itemSequence" column="listitem"/>
      </composite-id>
      <property name="itemStatus" type="ccx.dao.hibernate.TrimmedChar" column="listitemstat"/>
   </class>
</hibernate-mapping>


ClubListPK.java
Code:
public class ClubListPK implements Serializable {
   
   private String listDay;
   private Integer listNumber;

   public String getListDay() {
      return (this.listDay);
   }

   public void setListDay(String listDay) {
      this.listDay = listDay;
   }

   public Integer getListNumber() {
      return (this.listNumber);
   }

   public void setListNumber(Integer listNumber) {
      this.listNumber = listNumber;
   }

   public boolean equals (Object o) {
      // Return true if this are the same instance
      if (this == o) {
         return true;
      }
      if (o == null || !(o.getClass() != getClass())) {
         return false;
      }
      
      // Casting o to our object is safe now
      ClubListPK o2 = (ClubListPK)o;
      
      // Compare the fields for equality
      return
         EqualsUtil.areEqual(getListDay(), o2.getListDay()) &&
         EqualsUtil.areEqual(getListNumber(), o2.getListNumber());
   }
   
   public int hashCode () {
      int result = HashCodeUtil.SEED;
      result = HashCodeUtil.hash( result, getListDay() );
      result = HashCodeUtil.hash( result, getListNumber() );
      return result;
   }
   
   public String toString () {
      return listDay + "-" + listNumber;
   }
   
}

ClubList.java
Code:
public class ClubList implements Serializable {
   private ClubListPK key;
   private String clubCode;

   public boolean equals (Object o) {
      // Return true if this are the same instance
      if (this == o) {
         return true;
      }
      if (o == null || !(o.getClass() != getClass())) {
         return false;
      }
      
      // Casting o to our object is safe now
      ClubList o2 = (ClubList)o;
      
      // Compare the fields for equality
      return
         EqualsUtil.areEqual(getKey(), o2.getKey());
         
   }
   
   public int hashCode () {
      int result = HashCodeUtil.SEED;
      result = HashCodeUtil.hash( result, getKey() );

      return result;
   }

   public void setKey (ClubListPK key) {
      this.key = key;
   }
   public ClubListPK getKey () {
      return this.key;
   }

   public String getClubCode() {
      return (this.clubCode);
   }

   public void setClubCode(String clubCode) {
      this.clubCode = clubCode;
   }
   public List getItems() {
      return (this.items);
   }

   public void setItems(List items) {
      this.items = items;
   }
}

ListItem.java
Code:
public class ListItem implements Serializable {
   private ClubList clubList;
   private int itemSequence = 1;
   private String itemStatus = STATUS_AVAILABLE;

   public boolean equals (Object o) {
      // Return true if this are the same instance
      if (this == o) {
         return true;
      }
      if (o == null || !(o.getClass() != getClass())) {
         return false;
      }
      
      // Casting o to our object is safe now
      ListItem o2 = (ListItem)o;
      
      // Compare the fields for equality
      return
         EqualsUtil.areEqual(getClubList(), o2.getClubList()) &&
         EqualsUtil.areEqual(getItemSequence(), o2.getItemSequence());
   }
   
   public int hashCode () {
      int result = HashCodeUtil.SEED;
      result = HashCodeUtil.hash( result, getClubList() );
      result = HashCodeUtil.hash( result, getItemSequence() );
      return result;
   }
   
   public ClubList getClubList() {
      return (this.clubList);
   }

   public void setClubList(ClubList clubList) {
      this.clubList = clubList;
   }

   public int getItemSequence() {
      return (this.itemSequence);
   }

   public void setItemSequence(int itemSequence) {
      System.out.println ("***DEBUG: setItemSequence: " + itemSequence);
      this.itemSequence = itemSequence;
   }

   public String getItemStatus() {
      return (this.itemStatus);
   }

   public void setItemStatus(String itemStatus) {
      this.itemStatus = itemStatus;
   }

}



The ClubList object that I am testing with has these values:
listDay = 158
listNumber = 1
It has 3 children with the itemSequences: 1, 2, and 3

Here is the test code:
Code:
public void testClubList () throws Exception {
   debug("START testClubList()");
   Session s = ((CCXHibernateSession)ccxSession).getHsFactory().openSession(db);
   Transaction tx = null;
   try {
      tx = s.beginTransaction();
      debug("Loading ClubList object...");
      ClubList list = (ClubList)s.load(ClubList.class, new ClubListPK("158",new Integer(1)));
      debug("OK. Class = " + list.getClass());
      debug("*** ClubList.toString() ***");
      debug(list.toString());
      debug("***************************");
      tx.commit();
   } catch (Exception e) {
      e.printStackTrace();
      if (tx != null) {
         tx.rollback();
      }
   } finally {
      s.close();
   }

   debug("END testClubList()");
}


And finally, here is the output:
Code:
Loading ClubList object...
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
OK. Class = class ccx.beans.cls.ClubList
*** ClubList.toString() ***
Hibernate: select items0_.listday as listday__, items0_.listnum as listnum__, items0_.listitem as listitem__, items0_.listday as listday0_, items0_.listnum as listnum0_, items0_.listitem as listitem0_, items0_.listitemstat as listitem4_0_ from listdet items0_ where items0_.listday=? and items0_.listnum=?
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 1
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 1
Hibernate: select listitem0_.listday as listday0_, listitem0_.listnum as listnum0_, listitem0_.listitem as listitem0_, listitem0_.listitemstat as listitem4_0_ from listdet listitem0_ where listitem0_.listday=? and listitem0_.listnum=? and listitem0_.listitem=?
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 2
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 2
Hibernate: select listitem0_.listday as listday0_, listitem0_.listnum as listnum0_, listitem0_.listitem as listitem0_, listitem0_.listitemstat as listitem4_0_ from listdet listitem0_ where listitem0_.listday=? and listitem0_.listnum=? and listitem0_.listitem=?
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 3
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: setItemSequence: 3
Hibernate: select listitem0_.listday as listday0_, listitem0_.listnum as listnum0_, listitem0_.listitem as listitem0_, listitem0_.listitemstat as listitem4_0_ from listdet listitem0_ where listitem0_.listday=? and listitem0_.listnum=? and listitem0_.listitem=?
158-1:V28,null,INC,0/0
ListItems:
***************************
END testClubList()


Notice the lack of children in this:
Code:
158-1:V28,null,INC,0/0
ListItems:


Thank you in advance


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 25, 2004 2:08 pm 
Newbie

Joined: Mon May 10, 2004 1:10 pm
Posts: 5
Well, out of desparation, I've been trying many different configurations. Most recently, I tried removing the ListItem mapping altogether and instead map the ListItemS within the ClubList mapping using a composite-element. Like this:
Code:
<hibernate-mapping package="ccx.beans.cls">
   <class name="ClubList" table="listhdr">
      <composite-id name="key" class="ccx.beans.cls.ClubListPK">
         <key-property name="listDay" column="listday" type="ccx.dao.hibernate.TrimmedChar" />
         <key-property name="listNumber" column="listnum"/>
      </composite-id>
      <property name="clubCode" type="ccx.dao.hibernate.TrimmedChar" column="clubcode"/>
      <list name="items" table="listdet" lazy="true">
         <key>
            <column name="listday"/>
            <column name="listnum"/>
         </key>
         <index column="listitem"/>
         <composite-element class="ListItem">
            <property name="itemStatus" type="ccx.dao.hibernate.TrimmedChar" column="listitemstat"/>
         </composite-element>
      </list>

   </class>
</hibernate-mapping>


I removed the clubList reference to the parent that used to be inside of ListItem.java so now it is a uni-directional relationship, i.e. ListItem maintains no reference to its parent ClubList now.

Using the same test code as above, I get this output:
Code:
START testClubList()
Loading ClubList object...
Hibernate: select clublist0_.listday as listday0_, clublist0_.listnum as listnum0_, clublist0_.clubcode as clubcode0_ from listhdr clublist0_ where clublist0_.listday=? and clublist0_.listnum=?
***DEBUG: ClubList.setItems() called
Hibernate: select items0_.listitemstat as listitem3___, items0_.listday as listday__, items0_.listnum as listnum__, items0_.listitem as listitem__ from listdet items0_ where items0_.listday=? and items0_.listnum=?
***DEBUG: setItems(): 0
OK. Class = class ccx.beans.cls.ClubList
*** ClubList.toString() ***
159-1:V28,null,INC,0/0
ListItems:
***************************
END testClubList()

Once again, the SQL generated looks good, the ClubList loads fine, but the ClubList's listItems collection is empty???

Any help is appreciated.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 28, 2004 1:22 pm 
Newbie

Joined: Mon May 10, 2004 1:10 pm
Posts: 5
OK, I figured this out. It all had to do with my equals() implementation. As part of it, I was doing:
Code:
!(o.getClass() != getClass())


I changed it to:
Code:
!(o instanceof [class name here])


After thinking about how Hibernate works, this makes sense.


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.