-->
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.  [ 11 posts ] 
Author Message
 Post subject: Inheritance/PolymorphismProblem with CGLIB generated Proxies
PostPosted: Fri Nov 11, 2005 6:43 am 
Newbie

Joined: Fri Nov 11, 2005 6:38 am
Posts: 4
Hibernate version:[3.05 and 3.1rc2]

we use polymorphism in our persistent classes; we have
three classes:

class T
class S extends T
class L

L has a reference that is formally typed to T. At runtime,
instances of S (T's subclass) may be in L's collection of Ts.

So, if Hibernate (re-)loads L's collection of Ts, it instantiates
CGLIB proxies. Unfortunately, the proxies used for instances of
S are actually T$$EnhancerByCGLIB$$6b951e4b - its the proxy of the
base class!

This means that polymorphism doesn't work anymore.

Does anybody know how to get the subclass S or a proxy for the subclass S? The easiest thing to do is to turn off Hibernate's use of CGLIB using the property

hibernate.cglib.use_reflection_optimizer = false

Unfortunately, even if we use this setting, we still get these super-type proxy classes at runtime - it seems like Hibernate would ignore the above property setting.

Any help would be appreciated!

Thanks,
Markus & Navid


Top
 Profile  
 
 Post subject: Re: Inheritance/PolymorphismProblem with CGLIB generated Pro
PostPosted: Fri Nov 11, 2005 6:51 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
vahdat wrote:
This means that polymorphism doesn't work anymore.


On the contrary. If you were actually using polymorphism, instead of evil typecasting/instanceof, then you would not even notice this!

Back to Principles of OOP 101 for you guys!

vahdat wrote:
Does anybody know how to get the subclass S or a proxy for the subclass S?


Sure. Turn off lazy fetching. It's simply conceptually impossible to proxy a polymorphic association without breaking instanceof. You will realize this if you spend five minutes thinking about it.

Alternatively, you can use the bytecode pre-processor together with lazy="no-proxy" in HB 3.1.

But of course the best solution is never ever ever use instanceof in business logic! This is just basic OOP.

vahdat wrote:
The easiest thing to do is to turn off Hibernate's use of CGLIB using the property


The "refection optimizer" has NOTHING to do with proxies. Read the documentation.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 7:49 am 
Newbie

Joined: Fri Nov 11, 2005 6:38 am
Posts: 4
Hi Gavin,

first of all, thank you for the timely reply. We're really new to using hibernate and your references are a good startingpoint to find out more about the relevant hibernate concepts.

You are right, that using instanceof is generaly a bad idea. It is common practice though, in Java to use tagging interfaces. In our case, we use OpenArchitecureWare to generate code, expressing type information with tagging interfaces.

Using properties, we need to implant tagging properties on a very high inheritance level and add the respective value properties to all classes, thus being forced to ask all objects first if the value property has a meaning in the context of this Object and only then use it.

Cheers,
Navid[/quote]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 7:56 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
"Tagging interfaces" should not be mapped. So Hibernate should not be creating any proxies of "tagging interface" type.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 7:58 am 
Newbie

Joined: Fri Nov 11, 2005 7:42 am
Posts: 1
gavin wrote:
"Tagging interfaces" should not be mapped. So Hibernate should not be creating any proxies of "tagging interface" type.


we don't map the interface.

But we want to use instanceof on a mapped type to find out
whether this type is marked by the respective interface.

M.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 8:19 am 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
mv wrote:
gavin wrote:
"Tagging interfaces" should not be mapped. So Hibernate should not be creating any proxies of "tagging interface" type.


we don't map the interface.

But we want to use instanceof on a mapped type to find out
whether this type is marked by the respective interface.

M.

This is known lazy proxy limitalion (there are more limitations like public fields, final classes, private constructors .... ). So you need to avoid some "common practice" and to find alternative ways. You can initialize proxy and unwrapp in this case (See hibernateProxy interface). Probably there are more workarounds too.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 8:27 am 
Beginner
Beginner

Joined: Fri Oct 28, 2005 10:46 am
Posts: 37
It's odd how the number of posts in this topic keeps decreasing instead of the typical increase one sees.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 11, 2005 8:30 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
zzantozz wrote:
It's odd how the number of posts in this topic keeps decreasing instead of the typical increase one sees.


Yes, very annoying.

If only people would follow the forum rules....


Top
 Profile  
 
 Post subject: Re: Inheritance/PolymorphismProblem with CGLIB generated Pro
PostPosted: Fri Nov 11, 2005 10:04 am 
Newbie

Joined: Fri Nov 11, 2005 6:38 am
Posts: 4
gavin wrote:
Turn off lazy fetching.

Alternatively, you can use the bytecode pre-processor together with lazy="no-proxy" in HB 3.1.


I inserted lazy="no-proxy" in one-to-many and many-to-one relations, lazy="false" in properties and sets and used the instrument-taks to modify the bytecode.

I can see, that the bytecode is the way I need it: The relevant subclass is modified to implement a cglib interface.

Still, when I run the test, the class is replaced by a superclass-proxy. Did I misinterpret Gavin's advice?

Btw: The problem turned out to go beyond loosing tagging-interfaces: The proxy calls the superclass' methods, not the overwritten methods of the subclass it should proxy, thus destroying our event handling mechanisms.

Most likely I'm doing my hibernate-mapping is badly wrong. I just can't imagine noone else experiencing this problem.

Thanks for help :-)
Navid


Top
 Profile  
 
 Post subject: Re: Inheritance/PolymorphismProblem with CGLIB generated Pro
PostPosted: Fri Nov 11, 2005 10:10 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
vahdat wrote:
Still, when I run the test, the class is replaced by a superclass-proxy. Did I misinterpret Gavin's advice?


The proxy is stripped out when you access the field.

You havn't actually tested it properly, you're just playing with your debugger.

vahdat wrote:
Btw: The problem turned out to go beyond loosing tagging-interfaces: The proxy calls the superclass' methods, not the overwritten methods of the subclass it should proxy, thus destroying our event handling mechanisms.


Nonsense. The proxy of course delegates to the overriding method.


Top
 Profile  
 
 Post subject: Re: Inheritance/PolymorphismProblem with CGLIB generated Pro
PostPosted: Fri Nov 11, 2005 11:00 am 
Newbie

Joined: Fri Nov 11, 2005 6:38 am
Posts: 4
gavin wrote:
Nonsense.


Seems like I missed a lazy="false" at one point in my template.

It's working now.

Thanks a lot,
Navid


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