-->
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.  [ 6 posts ] 
Author Message
 Post subject: Problem in a Polymorphic Load()
PostPosted: Wed May 16, 2007 2:26 pm 
Newbie

Joined: Mon Oct 23, 2006 10:08 am
Posts: 7
Location: Buenos Aires - Argentina
I have a hierarchy of classes using the table-per-subclass strategy, when i use the Load() method to get a persistent class specifying the top class of the hierarchy i obtain a Proxy.
If i use NHibernateUtil.GetClass() with the Proxy it returns the right Type of the class (a child class), but if i try to cast it to that Type i get an error, i dont know how to cast to the real class?

Here's an example:
Code:
Class A;
Class B : A;

A a = Session.Load(typeof(A),1); //i have a persistent instance of B with id = 1

NHibernateUtil.GetClass(a); //it returns typeof(B) what's true

B b = (B)a; it's throw an Exception!!!!


If i use Get() instead of Load() it returns a instance of the real class, its that the solution?


Hibernate version: 1.2.GA
.NET Framework: 1.1


Top
 Profile  
 
 Post subject: Re: Problem in a Polymorphic Load()
PostPosted: Wed May 16, 2007 3:51 pm 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
estebancaillou wrote:
I have a hierarchy of classes using the table-per-subclass strategy, when i use the Load() method to get a persistent class specifying the top class of the hierarchy i obtain a Proxy.
If i use NHibernateUtil.GetClass() with the Proxy it returns the right Type of the class (a child class), but if i try to cast it to that Type i get an error, i dont know how to cast to the real class?


see http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html_single/#performance-fetching-proxies

This is why I personally do not use proxies for types which use inheritance. Not being able to use == is what bothers me the most, not the casting, but the casting could also be an issue.


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 16, 2007 4:57 pm 
Expert
Expert

Joined: Tue Aug 23, 2005 5:52 am
Posts: 335
If you use Load for the correct subclass of the same objectit will return the correct proxy. From the documentation (in section 15.1.3 of the 1.2.0 docs):

<snip>

There are some gotchas to be aware of when extending this approach to polymorphic classes, eg.

Code:
<class name="Cat" proxy="Cat">
    ......
    <subclass name="DomesticCat">
        .....
    </subclass>
</class>


Firstly, instances of Cat will never be castable to DomesticCat, even if the underlying instance is an instance of DomesticCat:

Code:
Cat cat = (Cat) session.Load(typeof(Cat), id);  // instantiate a proxy (does not hit the db)
if ( cat.IsDomesticCat ) {                  // hit the db to initialize the proxy
    DomesticCat dc = (DomesticCat) cat;       // Error!
    ....
}


Secondly, it is possible to break proxy ==.
Code:
Cat cat = (Cat) session.Load(typeof(Cat), id);            // instantiate a Cat proxy
DomesticCat dc =
        (DomesticCat) session.Load(typeof(DomesticCat), id);  // acquire new DomesticCat proxy!
System.out.println(cat==dc);                            // false


However, the situation is not quite as bad as it looks. Even though we now have two references to different proxy objects, the underlying instance will still be the same object:
Code:
cat.Weight = 11.0;  // hit the db to initialize the proxy
Console.WriteLine( dc.Weight );  // 11.0


</snip>

The key part is:

DomesticCat dc =
(DomesticCat) session.Load(typeof(DomesticCat), id); // acquire new DomesticCat proxy!


Note that this will not actually hit the DB again - it will just create a new proxy for the underlying object that's already in the session. Using this will break == but if that's not a problem at least it solves your other problem! :)

Cheers,

Symon.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 17, 2007 8:25 am 
Newbie

Joined: Mon Oct 23, 2006 10:08 am
Posts: 7
Location: Buenos Aires - Argentina
thanks to all

merge_s.rottem, what you say solve my problem, and if doesnt exist a better way i gona use it. But if i use Get() instead of Load() it returns the right class, its a valid solution too?

jchapman, what's the way to avoid proxys for classes which use inheritance? i know one way is no using lazy init in many-to-one and one-to-one relationship, but in a Polymorphic Load? using Get()?

Sorry my english and thaks for your time.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 17, 2007 9:51 am 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
estebancaillou wrote:
jchapman, what's the way to avoid proxys for classes which use inheritance? i know one way is no using lazy init in many-to-one and one-to-one relationship, but in a Polymorphic Load? using Get()?


Just put lazy="false" in your mapping file for all class/subclass/joined-subclass entries in the inheritance chain. Whenever you load using Get() or Load() it will pull the real class, not the proxy.


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 17, 2007 9:56 am 
Newbie

Joined: Mon Oct 23, 2006 10:08 am
Posts: 7
Location: Buenos Aires - Argentina
thanks again jchapman, i didnt know i can do that.


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