[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