Announcement Announcement Module
No announcement yet.
Hibernate 4 Multi-Tenancy and Spring 3 Hibernate Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Hibernate 4 Multi-Tenancy and Spring 3 Hibernate

    Hi, All

    I was evaluating Multi-Tenancy feature present in Hibernate 4(4.1.0), but was not able to get it working with HibernateTransaction setting. I have defined settings as follows.

    LocalSessionFactoryBean :

    public class Configuration {
    	@Inject private DataSource dataSource;
    	@Inject private MultiTenantConnectionProvider multiTenantConnectionProvider;
    	public LocalSessionFactoryBean sessionFactory() throws IOException{
    		LocalSessionFactoryBean bean = new LocalSessionFactoryBean();
    		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="" />
    	<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"
    		depends-on="sessionFactory" >
    		  <property name="sessionFactory" ref="sessionFactory"></property>
    		  <property name="dataSource" ref="dataSource"></property>
    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

  • #2
    I'm evaluating as well. I let you know when I'm done testing.


    • #3
      For my part, I'm testing multiTenacy DATABASE.

      I have 2 datasources (1 DB each / commons-dbcp), 2 org.hibernate.service.jdbc.connections.internal.Da tasourceConnection ProviderImpl pointing to each datasource.

      I have a custom MultiTenantConnectionProvider

      import org.hibernate.service.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
      import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
      public class MultiTenantConnectionProvider extends AbstractMultiTenantConnectionProvider {
      	public ConnectionProvider getAnyConnectionProvider() {
      		return MultiTenantConnectionHolder.getAnyConnectionProvider();
      		//return MultiTenantConnectionHolder.getConnectionProvider("aidoomobile");
      	public ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
      		return MultiTenantConnectionHolder.getConnectionProvider(tenantIdentifier);
      And hibernate properties

      which currently doesn't work at startup :'( because the org.springframework.orm.hibernate4.LocalSessionFac toryBean afterPropertiesSet seems to try something with the ConnectionProvider which fails...

      Caused by: org.hibernate.HibernateException: Provider is closed!
      	at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(
      	at org.hibernate.service.jdbc.connections.spi.AbstractMultiTenantConnectionProvider.getAnyConnection(
      	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl$MultiTenantConnectionProviderJdbcConnectionAccess.obtainConnection(
      	at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(
      This is a little bit strange, but I let you know if I find something working.


      • #4
        I opened another thread for this topic, if it can help: