[hibernate-dev] Proxies and typing

Eric Dalquist eric.dalquist at doit.wisc.edu
Thu Jan 26 08:39:22 EST 2012


Perhaps an overloaded method for those that want generics and proxies?

public<T>  T load(Class<?>  entityType, Class<T>  proxyType, ...)

It is kinda gross and results in higher level code knowing about the 
proxies but it would work for those people that are using proxyClass 
without having to make lower level changes.

-Eric

On 1/25/12 10:54 PM, Steve Ebersole wrote:
> In terms of caching the resolution (User-UserImpl) on SessionFactory,
> if we go that route, we can just limit it to specified proxyClass
> values as opposed to a more free-form "any and all interfaces".
>
> Also, as far as the Session get and load methods, we don't have to
> switch them to use generics.  We can leave this feature for the load
> access stuff.
>
> On Wed 25 Jan 2012 10:48:30 PM CST, Steve Ebersole wrote:
>> 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



More information about the hibernate-dev mailing list