-->
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.  [ 12 posts ] 
Author Message
 Post subject: Subclass implementation
PostPosted: Tue Jul 17, 2007 1:19 am 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
Hi all,

I have an optimization question. Let's assume that we have main class:

class User
{
...
}


and classes with some properties with formula which uses SQL functions with large amount of different calculation:


class UserWithRate : User
{
...
}

class UserWithFullInfo : User
{
...
}

I reviewed "The Three Strategies" but non of listed strategy is suitable for me:
http://www.hibernate.org/hib_docs/nhibe ... strategies

I don't want one class which calculates all required (user + UserWithRate + UserWithFullInfo) properties but wanted to separate this functionality between different classes.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 17, 2007 4:26 am 
Beginner
Beginner

Joined: Wed Nov 29, 2006 10:32 am
Posts: 34
Why is the "use table for each subclass" = "joined-subclass" mapping not ok in this case? It will do additional joins, but for just 3 tables, this is almost certainly acceptable.
Regards
Harald


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 17, 2007 4:27 am 
Senior
Senior

Joined: Mon Aug 21, 2006 9:18 am
Posts: 179
I'd go back and reread those docs. The inheritance strategies outlined are not constraining you to have all methods/props in a single class, but rather is proposing different ways of mapping the object representation to the flattened relational model (table(s)).

So you can use the map your User.hbm.xml class
Code:
<class name="User" ... >
  //common properties in base

<subclass name="UserWithRate" discriminator="Rated">
   //properties
</subclass>
<subclass name="UserWithFullInfo" discriminator="YouCompleteMe">
   //properties
</subclass>
</class>


By the way, I'd look closer at my design if I were you and see if composition doesn't make better sense than inheritance here.

Hope this helps
Mike

_________________
If this helped...please remember to rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 10:20 am 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
mnichols wrote:
I'd go back and reread those docs. The inheritance strategies outlined are not constraining you to have all methods/props in a single class, but rather is proposing different ways of mapping the object representation to the flattened relational model (table(s)).


Thanks for your answer. I reviewed documentation again but didn't find answer. You suggest me the solution with discriminator but it's not suitable for me because I do not have discriminating value. I'll explain why:

Let's assume that you have class "User" which contains user information. In one of a form you need to show users list with their rate e.g. "formula" field from another table (COUNT(*) FROM UserRate where userid = :user). I do not want to know user rate everytime but only on this form.

The possible solution is to declare the class property one more time. But it would be great if I can somehow "extend" current class with another.

e.g.:
<code>
<class name="User, ..." table="dbo.[user]" lazy="false">

<id name="UserId" column="user_id" type="Int32" unsaved-value="0">
<generator class="native"/>
</id>
<property column="user_phone" type="String" name="UserPhone" length="150" />
<property column="user_email" type="String" name="UserEmail" length="150" />
<property column="user_status_id" type="Int32" name="UserStatusId" not-null="true" />
<property column="user_name" type="String" name="UserName" length="50" />

</class>

<class name="UserWithRate" inheritedClass="true">
<property name="Rates" formula="(SELECT COUNT(*) FROM UserRate AS cb WHERE cb.UserID = UserId)" />
</class>


class User
{
...
}

class UserWithRate : User
{
int Rates { ... }
}
</code>


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 12:44 pm 
Senior
Senior

Joined: Mon Aug 21, 2006 9:18 am
Posts: 179
Then simply use discriminator value of 'Standard' for the 'User' class and 'Rated' for the 'UserWithRate' class in your mappings...The discriminator value is only used internally by NHibernate and you wouldn't know about it.

There's no reason why using a discriminator value here won't work.

Take care
Mike

_________________
If this helped...please remember to rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 1:03 pm 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
Well I can set arbitrary discriminator-value for them. But what value should I set for <discriminator> of the base class. Discriminator should be set and pointing to a specific column.

mnichols wrote:
Then simply use discriminator value of 'Standard' for the 'User' class and 'Rated' for the 'UserWithRate' class in your mappings...The discriminator value is only used internally by NHibernate and you wouldn't know about it.

There's no reason why using a discriminator value here won't work.

Take care
Mike


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 1:17 pm 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
OK, I've tried the following solution - the base class with formula discriminator:

<class name="BaseClass" discriminator-value="0">
<discriminator formula="0" />

<subclass name="SubClass" discriminator-value="1">
</subclass>
</class>

It always returns for me null :(.

And can I somehow change the vlau in formula externally? E.g. lets assume that class "BaseClass" participates in IList collection of another class. And I'd like that instead of BaseClass there will be loaded SubClass.

Thanks for all your help!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 2:11 pm 
Senior
Senior

Joined: Mon Aug 21, 2006 9:18 am
Posts: 179
Here's an example of a discriminator tag:
Code:
    <discriminator>
      <column name="TypeCode" not-null="true" sql-type="nvarchar(25)" />
    </discriminator>


Remember that both types of your class (the inheritance hierarchy) are in the SAME TABLE and so will have different Id's. Therefore, you won't need to do a complex formula for the example you mentioned since the class that is referencing your other classes will do so by Id.

Try just using the discriminator tag I have above and provide meaningful names as discriminator-values, like 'StandardUser' or 'TypedUser'. Let NHib write out your schema (or manually add the 'TypeCode' column in your table) . I think you are thinking it's a bit more complex than it needs to be.

Take care
Mike

_________________
If this helped...please remember to rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 2:31 pm 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
The classes do not have descriptors. I just want that they contain different sets of properties. I know what is descriptor and how it can be used for subclasses. It's not that case.

Please reread what I wanted to archive. I wanted kind of HBM inheritance - base class provides common properties, other classes provides different set of properties which are specific for different situation.

E.g. I want UserRate property (which calculated as formula) in one form but it doesn't need in another, which I wanted only for example his number of Comments. Thus I'd like to provide 3 classes:

BaseUserClass

ClassWithUserRate : BaseUserClass
ClassWithUserNumberOfComments : BaseUserClass


Hope I'm clear here.


mnichols wrote:
Here's an example of a discriminator tag:
Code:
    <discriminator>
      <column name="TypeCode" not-null="true" sql-type="nvarchar(25)" />
    </discriminator>


Remember that both types of your class (the inheritance hierarchy) are in the SAME TABLE and so will have different Id's. Therefore, you won't need to do a complex formula for the example you mentioned since the class that is referencing your other classes will do so by Id.

Try just using the discriminator tag I have above and provide meaningful names as discriminator-values, like 'StandardUser' or 'TypedUser'. Let NHib write out your schema (or manually add the 'TypeCode' column in your table) . I think you are thinking it's a bit more complex than it needs to be.

Take care
Mike


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 08, 2007 2:41 pm 
Senior
Senior

Joined: Mon Aug 21, 2006 9:18 am
Posts: 179
Classes don't need to have 'descriptors'...
<discriminator> is only used by NHibernate to distinguish the type of class to instantiate internally. There is no need to have a property in your class to do this kind of distinction.

There won't need to be any kind of effect on your objects at all.

Are you thinking that I am telling you to alter your classes with an extra property for 'descriptors'? Not at all.

Take care
Mike

_________________
If this helped...please remember to rate it!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 09, 2007 2:07 am 
Newbie

Joined: Tue Oct 03, 2006 7:25 am
Posts: 8
mnichols wrote:
Classes don't need to have 'descriptors'...
<discriminator> is only used by NHibernate to distinguish the type of class to instantiate internally. There is no need to have a property in your class to do this kind of distinction.


Yes, I understand that. But the classes on DB level are also the same and this is a problem for me. Both classes (BaseUser & UserWithRate) has the same table and do not have discriminator column. The only difference is that class UserWithRate has additional column which provides UserRate which calculated through formula property.

Since such properties (with formulas and lots of calculation) maybe too much in one class it will affect performance and I'd like to separate this logic between different subclasses. I'm looking for a way how to do that.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 09, 2007 9:58 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
des wrote:
I wanted kind of HBM inheritance - base class provides common properties, other classes provides different set of properties which are specific for different situation.

E.g. I want UserRate property (which calculated as formula) in one form but it doesn't need in another, which I wanted only for example his number of Comments.


This is not possible with NH inheritance, because this is actually a violation of OO semantics. NH is strict with this: once an 'A', always an 'A'. An object isn't of one class in one situation, then another class in another. Of course, you can use a base class reference for an object, but it's underlying class does not change.

mnichols suggested using composition elsewhere; I would pursue that instead.


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