Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: SessionFactoryImplSessionBuilderImpl multiTenancy
PostPosted: Mon Feb 27, 2012 1:23 pm 
Newbie

Joined: Tue Aug 18, 2009 3:45 am
Posts: 2
When the SessionBuilderImpl opens the session, it expects to receive a tenantIdentier.

Code:
      public Session openSession() {
         return new SessionImpl(
               connection,
               sessionFactory,
               getTransactionCoordinator(),
               autoJoinTransactions,
               sessionFactory.settings.getRegionFactory().nextTimestamp(),
               interceptor,
               flushBeforeCompletion,
               autoClose,
               connectionReleaseMode,
               tenantIdentifier
         );
      }


But if I specify a CurrentTenantIdentifierResolver is the SessionFactoryImpl, I feel like it should determine the tenantIdentifier from that specific class instead of waiting for it to be initialize... ? no?


Top
 Profile  
 
 Post subject: Re: SessionFactoryImplSessionBuilderImpl multiTenancy
PostPosted: Tue Feb 28, 2012 4:20 am 
Newbie

Joined: Tue Aug 18, 2009 3:45 am
Posts: 2
Can also be around SessionFactoryImpl.openSession (around line 1008 in HB4.1.0.FINAL)

Code:
   public Session openSession() throws HibernateException {
      return withOptions().openSession();
   }


Shouldn't it request a tenantIdentifier from the specified MultiTenantIdentifierResolver as I'm specifying the strategy as MultiTenancy.DATABASE.

AND examples from Hibernate itself tells it!

Code:
session = sessionFactory.withOptions().tenantIdentifier( "jboss" ).openSession();


From: https://github.com/hibernate/hibernate- ... yTest.java


Top
 Profile  
 
 Post subject: Re: SessionFactoryImplSessionBuilderImpl multiTenancy
PostPosted: Wed Feb 29, 2012 12:24 pm 
Newbie

Joined: Wed Feb 29, 2012 5:55 am
Posts: 6
I have the same issue. After lot's of debugging I implemented a not-quick-but-dirty workaround. I don't use the real SessionFactoryImpl directly, but only through a dynamic proxy which overrides the #openSession() by #withOptions().tenantIdentifier(...).openSession(). Because SessionFactoryImpl is final, I wasn't override the method by subclassing. Additionally I had to implement the springs interface InfrastructureProxy and add an implementation for getWrappedObject(), because otherwise Springs SpringSessionContext wouldn't be able to find it's current session, opened by HibernateTransactionMonitor (using the proxy as key) and retrieved by SpringSessionContext (using the unproxied SessionFactoryImpl as key).
AOP wasn't a solution for this, because the final-modifier prevented subclassing by CGLIB (I'm not sure whether load-time-weaving were possible) and using dynamic proxies confused the SpringSessionContext.

In a first test it looks as it works fine (even if I'm not absolutely sure and would be happy to replace this hack by Hibernate 4.1.1). Does anybody know whether it'd be enough to override #openSession() with #withOptions().tenantIdentifier(...).openSession()?

Code:
public class CurrentTenantFixLocalSessionFactoryBean extends LocalSessionFactoryBean {

   public class CurrentTenantIdentifierResolverFixWrapper implements
         InvocationHandler {

      private final String openSessionMethod="openSession";
      private final String getWrappedObjectMethod="getWrappedObject";
      private SessionFactoryImplementor factory;

      public CurrentTenantIdentifierResolverFixWrapper(
            SessionFactoryImplementor f) {
         this.factory = f;
      }

      @Override
      public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
         CurrentTenantIdentifierResolver currentTenantIdentifierResolver = factory
               .getCurrentTenantIdentifierResolver();
         if (method.getName().equals(openSessionMethod) && method.getParameterTypes().length==0 && currentTenantIdentifierResolver != null) {
            SessionBuilder sb = factory.withOptions();
            String tenant = currentTenantIdentifierResolver.resolveCurrentTenantIdentifier();
            sb.tenantIdentifier(tenant);
            return sb.openSession();
         } else if (method.getName().equals(getWrappedObjectMethod) && method.getParameterTypes().length==0) {
            return factory;
         } else {
            return method.invoke(factory, args);
         }
      }
   }

   public SessionFactory getObject() {
      SessionFactoryImplementor realFactory = (SessionFactoryImplementor) super
            .getObject();
      SessionFactoryImplementor proxiedFactory= (SessionFactoryImplementor) Proxy
            .newProxyInstance(this.getClass().getClassLoader(),
                  new Class[] { SessionFactoryImplementor.class,
                        InfrastructureProxy.class },
                  new CurrentTenantIdentifierResolverFixWrapper(
                        realFactory));
      return proxiedFactory;
   }
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 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.