Announcement Announcement Module
Collapse
No announcement yet.
Hibernate 4 Multi-Tenancy and Spring 3 Hibernate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • 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 :

    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;
    	}
    
    }
    Configuration.xml :

    Code:
            <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

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

    Comment


    • #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

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

      Code:
      hibernate.multiTenancy=DATABASE
      hibernate.tenant_identifier_resolver=com.my.custom.MultiTenantIdentifierResolver
      hibernate.multi_tenant_connection_provider=com.my.custom.MultiTenantConnectionProvider
      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...

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

      Comment


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

        http://forum.springsource.org/showth...fier-specified

        Comment

        Working...
        X