Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate 4 Multi-Tenancy and Spring 3 Hibernate

All

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.

LocalSessionFactoryBean :

@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;
    }

}

Configuration.xml :

<context:component-scan base-package="com.green" />


    <context:annotation-config />

    <!-- Enable annotation style of managing transactions -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- Declare a datasource that has pooling capabilities -->
    <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" />

    <!-- Declare a transaction manager -->
    <bean id="transactionManager"
        class="com.green.saas.hibernate.SaasHibernateTransactionManager"
        depends-on="sessionFactory" >
          <property name="sessionFactory" ref="sessionFactory"></property>
          <property name="dataSource" ref="dataSource"></property>
    </bean>

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

  1. Session newSession = SessionFactoryUtils.openSession(getSessionFactory( ));
  2. (Session) ReflectionUtils.invokeMethod(openSessionMethod, sessionFactory) in openSession method
  3. Method openSessionMethod = ClassUtils.getMethod(SessionFactory.class, "openSession") above openSessionMethod argument is defined as.

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

Session newSession = getSessionFactory().withOptions().tenantIdentifier ( "abc" ).openSession();

or

class instance provided by hibernate property "hibernate.tenant_identifier_resolver" is called by which session is provided with tenant identifier.

To overcome this I extended class HibernateTransactionManager and override method doBegin and where new session is opened I opened it

getSessionFactory().withOptions().tenantIdentifier ( "abc" ).openSession();    

this makes thing click and work.

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.

Thanks in advance.

Hibernate - 4.1.0 Spring - 3.1.0

like image 979
baba.kabira Avatar asked Feb 14 '12 12:02

baba.kabira


People also ask

What is multi-tenancy in hibernate?

Multitenancy allows multiple clients or tenants use a single resource or, in the context of this article, a single database instance. The purpose is to isolate the information each tenant needs from the shared database. In this tutorial, we'll introduce various approaches to configuring multitenancy in Hibernate 5.

What is multi-tenant in spring?

Multi-tenancy refers to an architecture in which a single instance of a software application serves multiple tenants or customers. It enables the required degree of isolation between tenants so that the data and resources used by tenants are separated from the others.

What is the difference between multi-tenancy and virtualization?

In a multitenancy environment, multiple customers share the same application, in the same operating environment, on the same hardware, with the same storage mechanism. In virtualization, every application runs on a separate virtual machine with its own OS.


1 Answers

It looks like this feature was buggy on Hibernate side with the version you used: SPR-9222, HHH-7306.

Starting from Hibernate version 4.1.4 You should use CurrentTenantIdentifierResolver to pass the current tenant ID to SessionFactory.

like image 77
Roadrunner Avatar answered Oct 24 '22 11:10

Roadrunner