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).