-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Enabling Mutli tenant aware CacheImpl in SessionFactoryImpl
PostPosted: Wed Apr 18, 2012 7:23 pm 
Newbie

Joined: Wed Apr 18, 2012 6:32 pm
Posts: 1
This statement in version 4.1's documentation doesn't seem to be implemented....

Quote:
16.3.3. Caching

Multi-tenancy support in Hibernate works seamlessly with the Hibernate second level cache. The key used to cache data encodes the tenant identifier.

http://docs.jboss.org/hibernate/core/4.1/devguide/en-US/html/ch16.html


Code that encodes the identifier exists in the CacheKey constructor & I've traced it's use through to the Session etc. As near as I can tell the tenantId is used to encode the key's, but then when it comes time to decode in SessionFactoryImpl > CacheImpl. New CacheKey's constructed are done so with the tenantId is null.

The comment on line 1489 reads:
Quote:
// have to assume non tenancy.


So if the tenantId is indeed used to encode cache keys & then not used later to acess cached objects, how can CacheImpl in SessionFactoryImpl be functioning at all with keys that wouldn't match?

Is it really disabled as it seems or am I not understanding the code?


I understand it is not easy to get the tenantId in that section of code,
I imagine you'd have to use the CurrentTenantIdentifierResolver which is a contract I'm not able to implement in the context of my applications design.


What I was thinking of doing to get it working (if it isn't) was to extend the Cache interface creating methods that include a tenantId argument, the one place sure to have the correct tenantId would have to be the calling code. Then I'd have to override public Cache getCache(); in order to substitute my own CacheImpl that makes use of the extra tenantId argument in the creation of CacheKey.
Is this an appropriate solution?

I'd also of course then need to hunt around and figure out where to put my SessionFactoryImpl subclass, since hibernates architecture is still new to me.


Can anyone offer some insight or guidance on the topic > how to insure the statement made in the dev guide 16.3.3. Caching, is true.


Top
 Profile  
 
 Post subject: Re: Enabling Mutli tenant aware CacheImpl in SessionFactoryImpl
PostPosted: Fri Feb 21, 2014 4:14 am 
Newbie

Joined: Fri Feb 21, 2014 4:13 am
Posts: 1
I ran across the same issue. I was storing elements in a cache with a tenantId, but I found out that when evicting those elements the CacheImpl builds a CacheKey without a tenantId, so the hash of the key at evicting will never match the hash of the key that was used at storing.

Because I suspect I won't be the only one who struggled with this, here's my way around the issue:
I extended CacheImpl with a version that adds the correct tenantId to the CacheKey and because I was building the SessionFactory programatically I was able to replace the right services so that my CacheImpl was used in the SessionFactory.

Classes I build:
XXCacheImpl - as described above, builds CacheKey with tenantId
XXCacheServiceInitiator - implements SessionFactoryServiceInitiator<CacheImplementor>, creates XXCacheImpl
XXSessionFactoryServiceRegistryFactory - implements SessionFactoryServiceRegistryFactory, the buildServiceRegistry returns XXSessionFactoryServiceRegistryImpl
XXSessionFactoryServiceRegistryImpl - extends SessionFactoryServiceRegistryImpl but overrides createServiceBinding with the following implementation:
Code:
@Override
protected <R extends Service> void createServiceBinding(ServiceInitiator<R> initiator) {
   if (initiator instanceof CacheInitiator) {
      super.createServiceBinding(XXCacheServiceInitiator.INSTANCE);
   } else {
      super.createServiceBinding(initiator);
   }
}

I build the SessionFactory with a SessionFactory builder and a StandardServiceRegistryImpl. To add my own SessionFactoryServiceRegistryFactory to the StandardServiceRegistryImpl I call the next line before building the SessionFactory itself:
Code:
sr.locateServiceBinding(SessionFactoryServiceRegistryFactory.class).setService(new XXSessionFactoryServiceRegistryFactory(sr));

This approach is able to evict elements from the cache for a specific tenant.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.