-->
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.  [ 4 posts ] 
Author Message
 Post subject: How to load an Parent Object in a key-many-to-one relation?
PostPosted: Fri Jul 29, 2005 1:09 pm 
Senior
Senior

Joined: Tue Jan 11, 2005 5:03 pm
Posts: 137
Location: Montreal, Quebec
Hi,

I would like to know what is the best way to get the data (initialize an object) from a key-many-to-one relationship. I found some problem to get data from an object in a many-to-one relationship using the key-many-to-one tag.

I have theses 2 tables linked by a many-to-one relationship:

AstAccountRetail have theses primary keys (composite-key) :
ossAccount,
astSubAccount and
ossPlanType.

and AstAccount have theses primary keys:
ossAccount and
astSubAccount.

So, AstAccountRetail have a "many-to-one" relationship with AstAccount.

The artifact generator (from the Eclipse/Hibenate tools) generated a interesting mapping for the AstAccountRetail. It set AstAccount and ossPlanType as the primary keys.

Code:
<class
   name="AstAccountRetail"
   table="AstAccountRetail" schema="dbo" mutable="false">

   <composite-id name="id" class="AstAccountRetailId">
      <key-many-to-one name="astAccount" class="AstAccount">
         <column name="ossAccount" scale="18" precision="0" not-null="false" />
         <column name="astSubAccount" scale="10" precision="0" not-null="false" />
      </key-many-to-one>
      <key-property name="ossPlanType" type="TrimmedString">
         <column name="ossPlanType" scale="2" precision="0" not-null="true" sql-type="char" />
      </key-property>
   </composite-id>
   ...
</class>


All my tests worked fine, but I still have difficulty to browse to the AstAccount (the parent) object from the AstAccountRetail (a child). I would like to know why this object is not automatically loaded and initialized by Hibernate when I try to access it.

Should I explicitly load the AstAccount from the DB?

This is the code I use to load my AstAccountRetail (in a Spring context). As you can see, I create a AstAccount object to be passed in the AstAccount loader. Should I load (session.load) the AstAccount explicitly here? instead of generating a "detached" object?

Code:
   public AstAccountRetail findAstAccountRetailById(String ossAccount, String astSubAccount, String ossPlanType){
      Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
      
      AstAccountId accountId = new AstAccountId(ossAccount, astSubAccount);
      AstAccount account = new AstAccount(accountId);
      
      AstAccountRetail obj  = (AstAccountRetail) session.load(AstAccountRetail.class, new AstAccountRetailId(account, ossPlanType));
      return obj;
   }


And this is my test:

Code:
public void testFindAstAccountRetailById() {

   AstAccountRetail vo = DaoFinder.getAstAccountRetailDao().findAstAccountRetailById(ossAccount, astSubAccount, ossPlanType);
   
   assertEquals(ossAccount, vo.getId().getAstAccount().getId().getOssAccount());
   assertEquals(astSubAccount, vo.getId().getAstAccount().getId().getAstSubAccount());
   assertEquals(ossPlanType, vo.getId().getOssPlanType());
   
   assertEquals("SMITH", vo.getAstAccount().getAstLastName()); // HAVE A <NULL> VALUE HERE! TEST FAIL
}


And here the SQL generated by Hibernate, the AstAccount is never load (Hibernate usually would use an outer join):

Code:
select astaccount0_.ossAccount as ossAccount0_,
astaccount0_.astSubAccount as astSubAc2_0_,
astaccount0_.ossPlanType as ossPlanT3_0_,
astaccount0_.ossIsSpousal as ossIsSpo4_24_0_,
astaccount0_.ossIsLockedIn as ossIsLoc5_24_0_,
astaccount0_.ossIsPledge as ossIsPle6_24_0_,
astaccount0_.ossSpecialFee as ossSpeci7_24_0_,
astaccount0_.ossNonCalYearEnd as ossNonCa8_24_0_,
astaccount0_.ossEffectiveDate as ossEffec9_24_0_,
astaccount0_.ossEndDate as ossEndDate24_0_,
astaccount0_.ossBeneficiaryName as ossBene11_24_0_,
astaccount0_.ossBeneficiarySin as ossBene12_24_0_,
astaccount0_.ossBeneficiaryOther as ossBene13_24_0_,
astaccount0_.ossIsResp as ossIsResp24_0_,
astaccount0_.ossBeneficiaryNumber as ossBene15_24_0_,
astaccount0_.astLastMaintUser as astLast16_24_0_,
astaccount0_.astLastMaintType as astLast17_24_0_,
astaccount0_.astLastMaintJob as astLast18_24_0_,
astaccount0_.astLastMaintTime as astLast19_24_0_,
astaccount0_.astLastMaintDate as astLast20_24_0_

from dbo.AstAccountRetail astaccount0_ where astaccount0_.ossAccount=? and astaccount0_.astSubAccount=? and astaccount0_.ossPlanType=?



So the question I have is, should I session.load() the AstAccount explicitly before passing it in the id of AstAccountRetail? But I guess this code would "smell": I would not like to "load" an parent object because I need to load another one (the child).

Or is there a error in the way I get the AstAccountRetail?

Thanks for helping.

Etienne.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 2:55 pm 
Senior
Senior

Joined: Tue Jan 11, 2005 5:03 pm
Posts: 137
Location: Montreal, Quebec
Hi,

I didn't have any response to this post. I will try to clarify it:

I have these 2 table :

tableA have theses primary keys (composite-key) :
Prop1,
Prop2,
Prop3


and TableB have theses primary keys:
Prop1 and
Prop2.


This is my mapping for tableA:

Code:
<class
   name="TableA"
   table="TableA">

   <composite-id name="id" class="TableAId">
      <key-many-to-one name="TableA" class="TableA">
         <column name="Prop1"/>
         <column name="Prop2"/>
      </key-many-to-one>
      <key-property name="Prop3">
         <column name="Prop3" />
      </key-property>
   </composite-id>
   ...
</class>


TableA have a many-to-one relationship with TableB.

And this is my DAO function for tableA

Code:
   public TableA findTableAById(String Prop1, String Prop2, String Prop3){
      Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
     
      TableAId tableAId  = new TableAId(Prop1, Prop2);
      TableA tableA = new TableA(tableAId);
     
      TableB tableB  = (TableB) session.load(TableB.class, new TableBId(tableA, Prop3));
      return tableB;
   }



Is that the correct way to load tableA? When I try to get the parent of tableA -- tableA.getTableB() -- I get a uninitialized tableB object. What would be the correct way to do that?

Many thanks.

Etienne.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 2:59 pm 
Senior
Senior

Joined: Tue Jan 11, 2005 5:03 pm
Posts: 137
Location: Montreal, Quebec
Sorry, the last function should be read:


Code:
   public TableA findTableAById(String Prop1, String Prop2, String Prop3){
      Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
     
      TableBId tableBId  = new TableBId(Prop1, Prop2);
      TableB tableB = new TableB(tableBId);
     
      TableA tableA  = (TableA) session.load(TableA.class, new TableAId(tableB, Prop3));
      return tableA;
   }


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 01, 2005 4:39 pm 
Senior
Senior

Joined: Tue Jan 11, 2005 5:03 pm
Posts: 137
Location: Montreal, Quebec
OK,

didn't have many answers, so this is my solution if somebody in 20 years need the answer for a similiar problem.

But I am not sure this is the most optimized one. This solution will need 2 Selects instead of a One outer join :

Code:
   public AstAccountRetail findAstAccountRetailById(String ossAccount, String astSubAccount, String ossPlanType){
      Session session = SessionFactoryUtils.getSession(getSessionFactory(), true);
      AstAccountId accountId = new AstAccountId(ossAccount, astSubAccount);
      AstAccount account = (AstAccount)session.load(AstAccount.class,accountId );
      AstAccountRetail obj  = (AstAccountRetail) session.load(AstAccountRetail.class, new AstAccountRetailId(account, ossPlanType));
      return obj;
   }



Thanks
All

Etienne.


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