title: Hibernate 4 Multi-Tenancy and Spring 3 Hibernate
body: <p>All</p>
  
  <p>I was evaluating Multi-Tenancy feature present in Hibernate 4(4.1.0) along with Spring 3(3.1.0), but was not able to get it working with HibernateTransaction setting. I have defined settings as follows.</p>
  
  <p><strong>LocalSessionFactoryBean :</strong></p>
  
  <pre><code>@org.springframework.context.annotation.Configuration
  public class Configuration {
  
      @Inject private DataSource dataSource;
      @Inject private MultiTenantConnectionProvider multiTenantConnectionProvider;
  
      @Bean
      public LocalSessionFactoryBean sessionFactory() throws IOException{
          LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
          bean.setDataSource(dataSource);
          bean.setPackagesToScan("com");
          bean.getHibernateProperties().put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider);
          bean.getHibernateProperties().put("hibernate.multiTenancy", "SCHEMA");
          bean.getHibernateProperties().put("hibernate.tenant_identifier_resolver", new CurrentTenantIdentifierResolverImpl());
          bean.setConfigLocation(new ClassPathResource("/hibernate.cfg.xml"));
          return bean;
      }
  
  }
  </code></pre>
  
  <p><strong>Configuration.xml :</strong></p>
  
  <pre><code>&lt;context:component-scan base-package="com.green" /&gt;
  
  
      &lt;context:annotation-config /&gt;
  
      &lt;!-- Enable annotation style of managing transactions --&gt;
      &lt;tx:annotation-driven transaction-manager="transactionManager" /&gt;
  
      &lt;!-- Declare a datasource that has pooling capabilities --&gt;
      &lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
          destroy-method="close" p:driverClass="${app.jdbc.driverClassName}"
          p:jdbcUrl="${app.jdbc.url}" p:user="${app.jdbc.username}" p:password="${app.jdbc.password}"
          p:acquireIncrement="5" p:idleConnectionTestPeriod="60" p:maxPoolSize="100"
          p:maxStatements="50" p:minPoolSize="10" /&gt;
  
      &lt;!-- Declare a transaction manager --&gt;
      &lt;bean id="transactionManager"
          class="com.green.saas.hibernate.SaasHibernateTransactionManager"
          depends-on="sessionFactory" &gt;
            &lt;property name="sessionFactory" ref="sessionFactory"&gt;&lt;/property&gt;
            &lt;property name="dataSource" ref="dataSource"&gt;&lt;/property&gt;
      &lt;/bean&gt;
  </code></pre>
  
  <p>If I use plain HibernateTransactionManager provided by spring 3 I get error tenant identifier not set, reason for this being, it opens a session as follows</p>
  
  <ol>
  <li><code>Session newSession = SessionFactoryUtils.openSession(getSessionFactory( ));</code></li>
  <li><code>(Session) ReflectionUtils.invokeMethod(openSessionMethod, sessionFactory)</code> in <code>openSession</code> method</li>
  <li><code>Method openSessionMethod = ClassUtils.getMethod(SessionFactory.class, "openSession")</code> above <code>openSessionMethod</code> argument is defined as.</li>
  </ol>
  
  <p>we can see that there is no hook where you can provide tenant-identifier as expected while opening a session with tenant-identifier e.g</p>
  
  <pre><code>Session newSession = getSessionFactory().withOptions().tenantIdentifier ( "abc" ).openSession();
  </code></pre>
  
  <p>or</p>
  
  <pre><code>class instance provided by hibernate property "hibernate.tenant_identifier_resolver" is called by which session is provided with tenant identifier.
  </code></pre>
  
  <p>To overcome this I extended class HibernateTransactionManager and override method doBegin and where new session is opened I opened it </p>
  
  <pre><code>getSessionFactory().withOptions().tenantIdentifier ( "abc" ).openSession();    
  </code></pre>
  
  <p>this makes thing click and work.</p>
  
  <p><strong>I just wanted to know, is this above approach fine or there is some setting that I am not aware of that makes it work out of the box.</strong></p>
  
  <p>Thanks in advance.</p>
  
  <p>Hibernate - 4.1.0
  Spring - 3.1.0 </p>