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.  [ 9 posts ] 
Author Message
 Post subject: Subclass retrieval using Table per class hierachy
PostPosted: Fri Sep 14, 2007 2:25 pm 
Newbie

Joined: Mon Jun 04, 2007 12:26 pm
Posts: 13
Location: Houston, Texas
Summary: I am having difficulty retrieving data from a single table if I have 2 related tables (current and history data), that map to different C# classes, but the historical C# class inherits from the current C# class. If I retrieve using the current data class, I'm getting both current and historical data.

Explanation:I'm going to try explaining this with words, but the sample code at the end of the posting probably make more sense. Here's what is happeniing:
1. Have 2 tables, 'Pay', 'PayHist' with subclasses using the table per class hierachy.
2. The base class and subclasses for the current and history data have all different C# class names. The mapping files reflect this.
3. Since the current and history classes have some common functionality, I have the history class inherit from the corresponding current class. For example, CreditHist inherits from Credit

Problem: When retrieving data using the current subclasses, ie Credit, I am also getting data from the current AND history tables.

Question: Since my CreditHist (which is mapped to table PayHist) is inheriting from Credit which is inheriting from Pay (which is mapped to table pay) does NHibernate ignore the xml mapping of CreditHist which is using the table PayHist and replace it with the mapping of Credit which is using the table Pay? If that's the case is there a different way to define these classes?
Actually I'm hoping this falls in the "it's such an obvious error" category and there's a simple solution.

Thanks for your help.
Diane

-----------------------------------------------------------------------
Here is some sample code demonstrating the problem:
Class Defintions -----
My Pay table class definitions are similar to this:
Code:
class Pay...
class Credit: Pay, ICredit
class Cash: Pay...

My PayHist table class definitions are similar to this:
Code:
class PayHist...
class CreditHist: Credit
class CashHist: Cash
Mappings -----
For the table Pay:
Code:
...  <class name="Domain.Pay" table="Pay" discriminator-value="0" >
    <id name="Id" column="ID" type="int" >
      <generator class="assigned"/>
    </id>
    <discriminator
       formula="(select n.subclass_name from numeric_code n where n.unique_id = TYPE_ID)"                       
      type="String"     
    />
  ...
   <subclass name="Credit"
              discriminator-value="CreditCardPayment">
    </subclass>

    <subclass name="Cash"
          discriminator-value="CashPayment">
    </subclass>
    ...


For the table PayHist:
Code:
...
  <class name="Domain.PayHist" table="PayHist" discriminator-value="0" >
    <id name="Id" column="ID" type="int" >
      <generator class="assigned"/>
    </id>
    <discriminator column="PAYMENT_CLASS_NAME"
    />
   ...
   <subclass name="CreditHist"
              discriminator-value="CreditCardPayment">
    </subclass>
    <subclass name="CashHist"
          discriminator-value="CashPayment">
    </subclass>
       ...


Top
 Profile  
 
 Post subject: Subclass retrieval using Table per class hierachy
PostPosted: Fri Sep 14, 2007 3:30 pm 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
I imagine that it's because your PayHist objects are Pay objects in your mappings.

Code:
    <subclass name="Cash"
          discriminator-value="CashPayment">
    </subclass>

    <subclass name="CashHist"
          discriminator-value="CashPayment">
    </subclass>


You would need different discriminator-values for each class, otherwise you are saying that they represent the exact same class. Try changing the CashHist subclass like so:
Code:
    <subclass name="CashHist"
          discriminator-value="CashHistPayment">
    </subclass>


Then you should be good to go...make sense?

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject: Re: Subclass retrieval using Table per class hierachy
PostPosted: Fri Sep 14, 2007 3:48 pm 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
dp wrote:
Actually I'm hoping this falls in the "it's such an obvious error" category and there's a simple solution.

Thanks for your help.
Diane


Today is your lucky day then. If you read the release documentation for 1.2 you will see that they changed how the table per class structure works. Now you must provide the where constraint to your subclass mapping when you define your subclass. NHibernate no longer fills it in for you. I believe that the previous code was buggy and certain conditions can not be met automatically by the framework, therefore they don't meet any conditions.

Add the where clause where you check for the discriminator and you are done.


Top
 Profile  
 
 Post subject: Re: Subclass retrieval using Table per class hierachy
PostPosted: Mon Sep 17, 2007 9:03 am 
Newbie

Joined: Mon Jun 04, 2007 12:26 pm
Posts: 13
Location: Houston, Texas
jlockwood wrote:
I imagine that it's because your PayHist objects are Pay objects in your mappings.

Then you should be good to go...make sense?


Unfortunately that won't work since I'm using a legacy database. I can't change the discriminator value.


Top
 Profile  
 
 Post subject: Re: Subclass retrieval using Table per class hierachy
PostPosted: Mon Sep 17, 2007 9:23 am 
Regular
Regular

Joined: Fri Jan 20, 2006 7:45 pm
Posts: 97
Location: San Antonio, TX
Quote:
Unfortunately that won't work since I'm using a legacy database. I can't change the discriminator value.


Understand, I'm in a similar situation myself. What if you you had abrastract Credit and Cash classes? Credit and Cash would inherit from the abstract classes as would CreditHist nad CashHist. That way if you queried on Cash it would not be the parent of CashHist? You would move common attributes to the base and break the inheritance that you currently have.

_________________
Dum spiro, spero
-------------------------------
Rate my post if it helps...


Top
 Profile  
 
 Post subject: Re: Subclass retrieval using Table per class hierachy
PostPosted: Mon Sep 17, 2007 9:55 am 
Newbie

Joined: Mon Jun 04, 2007 12:26 pm
Posts: 13
Location: Houston, Texas
jlockwood wrote:
Quote:
What if you you had abrastract Credit and Cash classes?

I was trying to avoid that since I have about 25 subclasses. Guess I have the typical 'lazy developer' syndrome - 'surely I can code something that involves less typing'. :-)
Thanks for the help.


Top
 Profile  
 
 Post subject: Re: Subclass retrieval using Table per class hierachy
PostPosted: Mon Sep 17, 2007 10:38 am 
Newbie

Joined: Mon Jun 04, 2007 12:26 pm
Posts: 13
Location: Houston, Texas
jchapman wrote:
... Now you must provide the where constraint to your subclass mapping when you define your subclass. NHibernate no longer fills it in for you. Add the where clause where you check for the discriminator and you are done.

Could you give me an example? I wasn't aware of a subclass mapping element for the where clause when defining multiple subclasses in one table.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 17, 2007 2:03 pm 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
I'm coming late to this one, but did you investigate using a "polymorphism='explicit'" attribute in your class mapping? It specifies that only objects of the requested type will retreived, not subclasses. (see here). This might solve your problem very quickly without forcing a code change.

However, it occurs to me that you might want to change your code anyway. For instance, presumably at some point existing Cash objects will be changed to CashHist objects as part of a archiving process. You should know that NH (and OOP in general) do not respond well to this. It would be better to implement a structure like this using a Role Pattern, or even just setting an "archive" bit.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 19, 2007 12:48 pm 
Newbie

Joined: Mon Jun 04, 2007 12:26 pm
Posts: 13
Location: Houston, Texas
Thanks for the suggestions. I ended up implementing the historical classes. I'm porting code from Smalltalk where we have an ORM very similar to NHibernate (which is why I picked it). In that implementation we had something similar to the "archive bit" you mentioned.
Thanks again.


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