-->
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] Mapping a Bag with Composite Keys
PostPosted: Wed Feb 11, 2009 6:00 pm 
Newbie

Joined: Wed Feb 11, 2009 5:48 pm
Posts: 2
I am having trouble mapping a collection of Bags for a Child Class (Sales Account Summary History) to a Parent Class (Sales Account Summary).
Each Sales Account Summary can have multiple Sales Account Summary Histories (so a 1:N relationship)

Problem:
It works perfectly when I do a saveorUpdate (meaning each element in the collection is saved properly).

When I load a Sales Account Summary, I receive the correct number of Adjustments, but the details of each adjustment are equal to the latest (or newest) adjustment so they are all the same. They are different in the database however which I confirmed.

:( Any feedback is greatly appreciated!

I have 2 tables: sales_account_summary and sales_account_summary_history

The following are the primary key structures of the tables.

Table: sales_account_summary
Code:
PK sales_account_id
PK yearmo
....


Table: sales_account_summary_history
Code:
PK sales_account_history_id
Blind FK sales_account_id
Blind FK yearmo
...


SalesAccountSummary Mapping
Code:
<hibernate-mapping>
   <class name="SalesAccountSummary" table="dbo.sales_account_summary" lazy="false">
      <composite-id>
         <key-property name="salesAccountId" column="sales_account_id" />
         <key-property name="yearMo" column="yearmo" />
      </composite-id>
      
      <property name="commissionEarned" column="commission_earned" />
      <property name="commissionPosted" column="commission_posted" />
      <property name="directCost" column="direct_cost" />
      <property name="directSales" column="direct_sales" />
      <property name="stockCost" column="stock_cost" />
      <property name="stockSales" column="stock_sales" />
      
      <property name="adjustmentReason" column="change_reason" />
      <property name="adjustmentUsername" column="username"   />      
         
      <!-- This is not working for some reason - not giving unique results-->
         <bag name="adjustmentHistory" lazy="false">         
         <key>
            <column name="sales_account_id" not-null="true"/>
            <column name="yearmo" not-null="true"/>               
         </key>      
         <one-to-many class="SalesAccountSummaryAdjustment" />
      </bag>
      
   </class>

</hibernate-mapping>


SalesAccountSummaryAdjustment Mapping
Code:
<hibernate-mapping>
   <class name="SalesAccountSummaryAdjustment" table="dbo.sales_account_summary_history" lazy="false">
      <composite-id>
         <key-property name="salesAccountId" column="sales_account_id" />
         <key-property name="yearmo" column="yearmo" />               
      </composite-id>
            
      <property name="id" column="sales_account_history_id"/>
      <property name="oldCommissionEarned" column="old_commission_earned"/>
      <property name="oldCommissionPosted" column="old_commission_posted"/>
      <property name="changeReason" column="change_reason" />
      <property name="timestamp" column="timestamp"/>
      <property name="username" column="username" />   
   
         
   </class>

</hibernate-mapping>


An example of getting a Sales Account Summary

Code:
   public SalesAccountSummary retrieveSalesAccountSummary(int accountId, int yearMo) {
      Session session = HibernateUtil.getCurrentSession();
      session.beginTransaction();
            
      Criteria crit = session.createCriteria(SalesAccountSummary.class);
      crit.add(Expression.eq("salesAccountId", new Integer( accountId )));
      crit.add(Expression.eq("yearMo", new Integer( yearMo )));
      SalesAccountSummary summary = (SalesAccountSummary)crit.uniqueResult();
      session.getTransaction().commit();
      
      return summary;
   }


Last edited by ep161302 on Thu Feb 12, 2009 12:14 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: How I Fixed It
PostPosted: Thu Feb 12, 2009 12:10 pm 
Newbie

Joined: Wed Feb 11, 2009 5:48 pm
Posts: 2
In case others experience this problem, the following where the steps I took to fix it.

Problem 1:
The SalesAccountSummaryAdjustment class did not implement the Serializable interface in addition to implement the equals() and hashCode() methods. This is important since Hibernate uses these methods to see if it has already added a result to the list. In my case, it was always adding the same result row for the number of rows in the result set.
The SalesAccountSummary class already did implemented Serializable and implemented the equals() and hashCode() methods.

The methods added to SalesAccountSummaryAdjustment:
Code:
   public boolean equals(Object obj) {
      if(!(obj instanceof SalesAccountSummaryAdjustment ))
         return false;
      
      SalesAccountSummaryAdjustment adj = (SalesAccountSummaryAdjustment) obj;
      return (adj.getYearmo() == getYearmo() && adj.getSalesAccountId() == getSalesAccountId() && adj.getId()==getId());
   }
   public int hashCode() {      
      return new Integer( getSalesAccountId()).hashCode() + new Integer( getYearmo()).hashCode() + new Integer( getId()).hashCode();
      
   } 


Problem 2:
Hibernate was still not hitting the equals() or hashCode() methods in SalesAccountSummaryHistory class because of a problem in the mappings. To be exact, the key mappings for SalesAccountSummaryAdjustment. I declared the keys as composite keys for salesAccountId and yearmo instead of just salesAccountHistoryId which is declared primary key in the database. The following is the change I made for the mappings.

From:
Code:
  <class name="SalesAccountSummaryAdjustment" table="dbo.sales_account_summary_history" lazy="false">
      <composite-id>
         <key-property name="salesAccountId" column="sales_account_id" />
         <key-property name="yearmo" column="yearmo" />               
      </composite-id>
             
      <property name="id" column="sales_account_history_id"/>
...
</class>


To:
Code:
   <class name="SalesAccountSummaryAdjustment" table="dbo.sales_account_summary_history" lazy="false">
      <id name="id" column="sales_account_history_id">
         <generator class="identity" />
      </id>
            
      <property name="salesAccountId" column="sales_account_id"/>
      <property name="yearmo" column="yearmo"/>

...
</class>


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.