我实现了Hibernate的多租户数据库架构,根据租户选择特定的数据库连接.我正在使用Spring 4.3和Hibernate 5.2.
当租户使用相同的RDBMS时,一切都很好,但是当他们不同时,我必须动态更改hibernate属性中的方言设置,我不知道如何.
我的hibernate属性在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>
Run Code Online (Sandbox Code Playgroud)
下面是Hibernate的CurrentTenantIdentifierResolver的实现:
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() …Run Code Online (Sandbox Code Playgroud) 如果我没有以编程方式设置任何内容,只需调用Configuration configuration = new Configuration().configure();并使用hibernate.properties(如下所示),一切都很有效.一旦我尝试以编程方式提供用户名,密码和连接URL,我就会得到一个奇怪的异常,暗示hbm文件.我错过了什么?
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://myEC2/mCruiseOnServerDB?autoReconnect=true&failOverReadOnly=false&maxReconnects=10
hsqldb.write_delay_millis=0
shutdown=true
hibernate.connection.username=root
hibernate.connection.password=mypwd
hibernate.connection.pool_size=2
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.c3p0.idle_test_period=300
hibernate.c3p0.timeout=120
Run Code Online (Sandbox Code Playgroud)
现在是hibernate.properties
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hsqldb.write_delay_millis=0
shutdown=true
hibernate.connection.pool_size=2
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
Run Code Online (Sandbox Code Playgroud)
代码
String connection = "jdbc:mysql://"
+ Globals.DBSERVER
+ "/mCruiseOnServerDB?autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
Configuration configuration = new Configuration()
.setProperty("hibernate.connection.url", connection)
.setProperty("hibernate.connection.username", Globals.DB_USER_NAME)
.setProperty("hibernate.connection.password", Globals.DB_PASSWORD);
configuration.configure();
sessionFactory = configuration
.buildSessionFactory(new ServiceRegistryBuilder()
.buildServiceRegistry());
Run Code Online (Sandbox Code Playgroud)
例外
我现在得到这个异常,一个用于mapping resource我的hbm文件中的每个条目.
11 May 2013 08:46:31,969 1300 [main] FATAL ReadOnlyOperations - Have chosen to ignore this runtime exception java.lang.UnsupportedOperationException: The application must supply JDBC …Run Code Online (Sandbox Code Playgroud)