-->
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.  [ 2 posts ] 
Author Message
 Post subject: Is hibernate's problem with method overriding fundamental ?
PostPosted: Tue Nov 15, 2005 2:37 pm 
Newbie

Joined: Mon Sep 19, 2005 4:30 am
Posts: 11
The ability to override methods is a fundamental feature of object orientation.
Proxies are a fundamental feature of hibernate.
Using both with hibernate poses some problems.

Proxies that are build as subclasses of mapped pojo classes suffer from the known problems coming from java's single inheritance model (leading to ClassCastExceptions when initializing proxies).

A remedy to this are proxies build from interfaces (see 20.1.3 hibernate reference: <class name="CatImpl" proxy="Cat">). With this approach a single proxy can implement all interfaces of a class hierarchy and thus allows for polymorphic lazy initialization.

This works great as long as there is no method overriding in the class hierarchy.

It seems that hibernate guesses to which interface a method belongs that is called upon a proxy. This is a problem as soon as methods are overridden in a class hierarchy (calling such a method upon the proxy faces it to the problem of having to choose between the different available methods with the same signature).

This unnecessarily limits the set of class hierarchies hibernate can use lazy loading upon and it limits the usefulness of the great hibernate feature of proxy interfaces.

As it is, not being able to cope with method overriding in general is a fundamental problem since hibernate sets out to be able to map arbitrary pojo classes.

On the other hand (and without knowing much of hibernate internals), it seems straight forward to fix the problem: if a method invocation is possible on more than one interface, hibernate should determine the discriminator-value for the instance at hand (would lead to a database hit).
This probably works only for the table-per-hierarchy mapping strategy.

Another, more general solution seems to be to try out all interfaces matching a method invocation until one fits (i.e. does not produce a class cast exception)
Of course, the basis for both solutions is the use of proxy interfaces




Hibernate version:3.0.5


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 24, 2005 1:14 pm 
Newbie

Joined: Mon Sep 19, 2005 4:30 am
Posts: 11
for a posting with the same problem including an example see

http://forum.hibernate.org/viewtopic.php?t=948339

Here is another way to state the problem:
A proxy class of the root of a class hierarchy implements all proxy interfaces of all classes in the hierarchy.
Two different interfaces IA and IB might each implement a method IA.m() and IB.m() with the same signature.
When calling m() on the proxy, how does the proxy know to which Interface m() belongs?
This question is important because the proxy casts the underlying object to one of the two interfaces.
Currently hibernate (3.0.5) seems to arbitrarily choose either IA or IB, which leads to a ClassCastException
depending on the actual type of the underlying persited object.
Besides the fact that there should not be thrown a ClassCastException this also shows that the behavior of
hibernate is not deterministic.

Remedy:
Do not mention m() more often than necessary in the Interfaces; mirror the class hierarchy with the interface hierarchy.
So if class A and class B are both subclasses of class R and there is a proxy interface IR with a method IR.m() let
IA and IB be extensions of IR. Do not mention IA.m() as an explicit member of IA (it is an implicit member of IA by
inheritance from IR). The analogue should be done for IB.m() an IB.

This does not solve the general problem of two different methods with the same signature in a class hierarchy
(such methods need not necessarily have a common ancestor method)
but it solves the very common problem of overridden methods in the class hierarchy.
(as long as you are free to edit the proxy interfaces).

Note:
Why should the inherited methods be redundantly mentioned in the proxy interfaces at all?
The simple reason my proxy interfaces declare all the methods of the superinterfaces as well is:
it is just one way to generate the proxy interfaces from the classes (and it does not change the
JAVA semantics with respect to simply inheriting them - see below).

Note:

If the interface IA extends IR and IR.m() is a member of IR then IA.m() is an implicit member of IA (through inheritance).
Making m() an explicit member of IA (by adding it to the definition of IA) does not change the Java semantics (at least as far as I know).
(Still it makes a difference for the generated proxies as we see from the above discussion).


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