[hibernate-dev] Proxies and typing
Steve Ebersole
steve at hibernate.org
Wed Jan 25 23:48:30 EST 2012
Not really following what you are advocating Sanne.
The problem with accepting the interface in the API is that we do not
track this information today. From a Session, I have no way to get from
User -> UserImpl unless I iterate every persister registered with the
SessionFactory and check its mapped class type against the incoming
interface. Yes we could start tracking such information but thats yet
even more data cached as part of the SessionFactory.
When you say that "the first case would work only in certain situations
even with the current code, depending if you actually get a proxy or
not", yes that is true but that is true specifically because at one
point very early on this proxy class generation code was changed to not
use the entity class as part of the proxy class definition when the
mapping specified an interface as the proxy. Before that change it used
to use entity class AND the proxy interface. What I am asking is
whether we want to switch back to that to help facilitate generic
signatures.
In psuedo-code, the User/UserImpl example below today results in
essentially this:
public class ProxyClassForUserImpl extends Object implements User, ... {
...
}
It used to initially result in:
public class ProxyClassForUserImpl extends UserImpl implements User, ... {
...
}
On 01/25/2012 05:00 PM, Sanne Grinovero wrote:
> Would it be acceptable for such a use case to demand to use the
> interface instead ?
>
> UserImpl u = (UserImpl) session.load( UserImpl.class, ... ) -> Illegal
> type exception
> User u = (User) session.load( User.class, ... ) -> Ok
>
> I think it would, as the first case would work only in certain
> situations even with the current code, depending if you actually get a
> proxy or not, so I would consider such code wrong even with the older
> API.
>
> It would only break this currently working code:
> User u = (User) session.load( UserImpl.class, ... )
>
> but it won't break at runtime, it would stop compiling.. which is a
> good warning imho. Existing code (already compiled) would throw a
> runtime exception though.
>
> -- Sanne
>
>
> On 25 January 2012 21:26, Steve Ebersole<steve at hibernate.org> wrote:
>> BTW, I did go back and verify that indeed the mismatch is with
>> @Proxy.proxyClass specifying an interface. Consider an example:
>>
>> @Entity
>> @Proxy(proxyClass=User.class)
>> public class UserImpl implements User {
>> ...
>> }
>>
>> You will never be able to cast proxies instance of this thing to
>> UserImpl. This call will fail with CCE:
>>
>> UserImpl u = (UserImpl) session.load( UserImpl.class, ... )
>>
>> get() may or may not work depending.
>>
>> This is the source of us not being able to offer generic signatures.
>>
>>
>> On Wed 25 Jan 2012 01:33:14 PM CST, Steve Ebersole wrote:
>>> In regards to the new "load access", a user asked why we don't
>>> leverage generics.
>>>
>>> The problem is the existence of @Proxy#proxyClass. We have the same
>>> issue with Session#load/get taking the entity Class. We can't use a
>>> generic sig like:
>>>
>>> public<T> T load(Class<T> entityType, ...)
>>>
>>> because at times we return objects that are not typed to<T>. I have
>>> to dive back into the specifics, but IIRC the problem is that we don't
>>> do the expected thing and have the generated proxy class extend from
>>> the entity class if @Proxy#proxyClass names an interface. I remember
>>> this change way back when, but the specifics of why escape me at the
>>> moment.
>>>
>>> IMO I think providing generic signatures would obviously be a great
>>> improvement. Is it enough to change this behavior?
>>>
>>> WDYT?
>>>
>>
>> --
>> steve at hibernate.org
>> http://hibernate.org
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
--
steve at hibernate.org
http://hibernate.org
More information about the hibernate-dev
mailing list