Hibernate multi-tenancy creates a runtime diagram

I am setting up multiple tenant support for a java web application using hibernate 4 and spring 4. The default schema is created and installed when the application starts. This scheme works great when you are not trying to support multi-user work.

Now I need to create a scheme for each new tenant who creates an account. This scheme may simply be a copy of the general scheme, since it will adhere to the same format.

How can I create new schemas that follow the same format as the default schema at runtime? It looks like the default schema is created when an instance of LocalSessionFactoryBean is created, since that is where I specify the display resources.

+6
source share
2 answers

I came up with a solution that solves my problem. I hope this is useful to someone there.

Thus, the main problem was limiting Hibernate to create a schema for a new client at runtime during a multi-tenant configuration.

"Hibernate does not support automatic export of a circuit in a tiered environment."


My solution to get around this limitation (using Spring) was to create a new LocalSessionFactoryBean that is set to NOT to support multi-tenancy. So basically I have two LocalSessionFactoryBeans.

  • Multi-Tenant LocalSessionFactoryBean, which is used for multi-tenant sessions.
  • Non Multi-Tenant LocalSessionFactoryBean, which is used to create tenant schemes using the configuration set in the spring file.


Spring Configuration

<!-- Multi-tenant SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <map> <entry key="hibernate.dialect" value="${hibernate.dialect}" /> <entry key="hibernate.hbm2ddl.auto" value="NONE" /> <!-- Multi-tenancy support --> <entry key="hibernate.multiTenancy" value="SCHEMA" /> <entry key="hibernate.tenant_identifier_resolver" value="${hibernate.tenant_identifier_resolver}" /> <entry key="hibernate.multi_tenant_connection_provider" value-ref="multiTenantConnectionProvider" /> </map> </property> <property name="mappingResources"> <list> <COMMON SCHEMA MAPPING RESOURCES /> </list> </property> </bean> <!-- SessionFactory capable of managing multi-tenant schemas --> <bean id="sessionFactorySchemaManager" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <map> <entry key="hibernate.dialect" value="${hibernate.dialect}" /> <entry key="hibernate.hbm2ddl.auto" value="CREATE" /> <!-- Multi-tenancy support --> <entry key="hibernate.multiTenancy" value="NONE" /> </map> </property> <property name="mappingResources"> <list> <TENANT SPECIFIC SCHEMA MAPPING RESOURCES /> </list> </property> </bean> 


The code used to create the schema

 public boolean createSchema(final String tenantId) throws SQLException { boolean result = false; if(_configuration != null && _dataSource != null) { // Get a local configuration to configure final Configuration tenantConfig = _configuration; // Set the properties for this configuration Properties props = new Properties(); props.put(Environment.DEFAULT_SCHEMA, tenantId); tenantConfig.addProperties(props); // Get connection Connection connection = DriverManager.getConnection(_dataSource.getUrl(), _dataSource.getUsername(), _dataSource.getPassword()); // Create the schema connection.createStatement().execute("CREATE SCHEMA " + tenantId + ""); // Run the schema update from configuration SchemaUpdate schemaUpdate = new SchemaUpdate(tenantConfig); schemaUpdate.execute(true, true); // Set the schema connection.createStatement().execute("SET SCHEMA " + tenantId + ""); // Set the result result = true; } else if(_configuration == null) { if(_LOGGER.isWarnEnabled()) { _LOGGER.warn("No configuration was specified for " + getClass().getSimpleName()); } } else if(_dataSource == null) { if(_LOGGER.isWarnEnabled()) { _LOGGER.warn("No dataSource was specified for " + getClass().getSimpleName()); } } return result; } 


Note that the _configuration in this code comes from Non Multi-Tenant LocalSessionFactoryBean

+5
source

You can solve your problem using eclipseLink. here are some usage references: https://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant as well as http://www.javacodegeeks.com/2012/02/sneak-peak-at-java-ee-7 -multitenant.html or if you want to use sleep mode, you can take a look at this: http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html and this example is multiple rental in sleep mode: https://gist.github.com/dipold/5700724 and http://www.devx.com/Java/Article/47817

+1
source

Source: https://habr.com/ru/post/982796/


All Articles