【发布时间】:2018-10-21 21:32:40
【问题描述】:
我实现了Hibernate's multitenant database architecture,根据租户选择特定的数据库连接。我正在使用 Spring 4.3 和 Hibernate 5.2。
当租户使用相同的 RDBMS 时一切都好,但当它们不同时,我必须动态更改休眠属性中的方言设置,我不知道如何。
我的休眠属性在 dispatcher-servlet.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example"/>
<mvc:annotation-driven/>
<context:property-placeholder location="classpath:application.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
<property name="packagesToScan">
<list>
<value>com.example.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.dialect">${hibernate.dialect}</prop>-->
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.example.multitenancy.CurrentTenantIdentifierResolverImpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.example.multitenancy.MultiTenantConnectionProviderImpl</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
下面是Hibernate的CurrentTenantIdentifierResolver的实现:
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return Helper.getTenantFromAuthentication(authentication);
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
及AbstractDataSourceBasedMultiTenantConnectionProviderImpl的实现:
public class MultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
@Override
protected DataSource selectAnyDataSource() {
return getDataSource("tenantId1");
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return getDataSource(tenantIdentifier);
}
private DataSource getDataSource(String prefix) {
Properties properties = new Properties();
try {
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties"));
} catch (IOException e) {
throw new RuntimeException();
}
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(properties.getProperty(prefix + ".driverClassName"));
dataSource.setUrl(properties.getProperty(prefix + ".url"));
dataSource.setUsername(properties.getProperty(prefix + ".username"));
dataSource.setPassword(properties.getProperty(prefix + ".password"));
return dataSource;
}
}
application.properties 文件如下所示:
tenantId1.driverClassName = org.postgresql.Driver
tenantId1.url = <...>
tenantId1.username = <...>
tenantId1.password = <...>
tenantId2.driverClassName = com.mysql.jdbc.Driver
tenantId2.url = <...>
tenantId2.username = <...>
tenantId2.password = <...>
有没有办法动态改变休眠方言?
【问题讨论】:
-
@nikesh,这看起来确实相关,但您能否详细说明如何获取现有配置并进行更改?我很乐意接受你的回答。
-
从 Spring 中获取 SessionFactory bean 并调用 GetConfiguration 方法。它不工作。在代码中使用 id : sessionFactory。
标签: java spring hibernate multi-tenant