jsr107/jsr107spec — Issue #34: Add CacheManager unwrap method
Author: gregrluck
Created: 2011-11-09 02:01:16+00:00
State: open

T Cache.unwrap(Class cls) was added with the following motivation:

In the spirit of what is provided in the JPA specification for the EntityManager I think it would be a valuable forward-looking feature to add the method " T unwrap(java.lang.Class cls)" to the CacheManager interface.

I've included this ability on the CacheInvocationContext to provide implementation specific access through the API without blind casts.

however as was pointed out in the same email thread (by the same person):

Yeah it would actually look like:

net.sf.ehcache.Cache cache = javax.cache.cache.unwrap(net.sf.ehcache.Cache.class);

That allows the API to be completely type-safe using generics and the Class.cast(Object) API.

which is obviously just doing a blind cast but hiding it in code instead.

The desire for this method came from the JPA 2.0 standard where if my understanding of the JPA API is correct this was added because the following is very common:

UserClass talks to EntityManagerProxy (installed by JEE container) delegates to EntityManagerImpl (provided by JPA provider)

Since JPA users very frequently want or need to access implementation specific functionality outside of the JPA spec the JPA authors added a getDelegate method (in 1.0) that was replaced with an unwrap method in 2.0. This is basically a way of standardizing the EntityManagerProxy class installed by the various different JEE containers so that the user can access the correct for the current transaction context underlying persistence providers EntityManager implementation. As far as I am aware this is not a common usage pattern for caching. My preferred solution to this would be to keep this kind of hook in to the underlying implementation outside the API entirely - if a usage pattern similar to the JPA one became very common I would much prefer providing a Cache Cache.getDelegate() method instead. This way the user is forced to cast the return to an impl specific type and it is made abundantly clear that what they are doing is an explicit blind cast - rather than hiding the delegate access and casting behind another method.

Similar arguments can/should be applied to the other places that this pattern has been used. I'm not an expert in the CDI/annotations world so I don't know how much water this argument holds in those cases but it may be worth taking another look at those original examples too.

Associated TC Issue: DEV-6481