Хотя ответ уже предоставлен выше, я публикую его снова с более подробной информацией,
Я согласен с тем, что Вы можете использовать MultiTenantConnectionProviderImpl
вместе с CurrentTenantIdentifierResolver
, я реализовал обе версии и я публикую свой код для получения дополнительной помощи.
Цель того и другого должна быть понята первой.
CurrentTenantIdentifierResolver
используется для определения того, какое соединение будет использоваться для данного арендатора, и для этого вам потребуется идентификация арендатора. Для логики идентификации арендатора вы можете переопределить это. В вашем случае это будет исправлено, т.е. вы всегда будете указывать на свою первую базу данных.
public class TenantIdentifierAndSchemaResolver implements CurrentTenantIdentifierResolver {
private String tenantIdentifier = "FIRST_DATABASE";
@Override
public String resolveCurrentTenantIdentifier() {
return this.tenantIdentifier;
}
/**
* Reason why it retuns a false is because we don't want to validate the
* tenant identifier in the current session.
*
* Please read below.
* {@link CurrentTenantIdentifierResolver#validateExistingCurrentSessions()}
*/
@Override
public boolean validateExistingCurrentSessions() {
return false;
}
public void setTenantIdentifier(String tenantIdentifier) {
this.tenantIdentifier = tenantIdentifier;
}
}
После этого вам необходимо реализовать MultiTenantConnectionProvider
, с помощью которого вы фактически переключите базу данных для входящего запроса.
public class CustomMultiTenantConnectionProvider implements MultiTenantConnectionProvider {
private static final long serialVersionUID = 9033113494774715973L;
private Logger LOG = LogManager.getLogger(CustomMultiTenantConnectionProvider.class);
private BasicDataSource dataSource;
public void setDataSource(BasicDataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Connection getAnyConnection() throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Fetching any connection >");
}
return dataSource.getConnection();
}
@Override
public Connection getConnection(String tenantIdentifier) throws SQLException {
Connection tenantSpecificConnection = dataSource.getConnection();
if (!StringUtils.isEmpty(tenantIdentifier)) {
Statement statement = tenantSpecificConnection.createStatement();
statement.executeQuery("use " + tenantIdentifier);
statement.close();
tenantSpecificConnection.setSchema(tenantIdentifier);
} else {
tenantSpecificConnection.setSchema(Constants.SOMEOTHER_DB);
}
return tenantSpecificConnection;
}
@Override
public void releaseAnyConnection(Connection connection) throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Releasing connection obtained by : getAnyConnection", connection);
}
connection.close();
}
@Override
public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("Releasing connection for : {}", tenantIdentifier);
}
connection.close();
}
/**
* does the connection provider has support for releasing connection and get
* back the connection as and when needed ?
*
* @return
*/
@Override
public boolean supportsAggressiveRelease() {
return false;
}
@SuppressWarnings("rawtypes")
@Override
public boolean isUnwrappableAs(Class arg0) {
return false;
}
@Override
public <T> T unwrap(Class<T> arg0) {
return null;
}
}
Вам необходимо объявить эти bean-компоненты в весенней конфигурации, а также указать это в конфигурации hibernate.
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="org.opensource.example" />
<property name="hibernateProperties">
<map>
<entry key="hibernate.hbm2ddl.auto" value="update"></entry>
<entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"></entry>
<entry key="hibernate.connection.charSet" value="UTF-8"></entry>
<entry key="hibernate.multiTenancy" value="SCHEMA"></entry>
<entry key="hibernate.tenant_identifier_resolver" value-ref="multitenantSchemaResolverAndTenantIdentifier"></entry>
<entry key="hibernate.multi_tenant_connection_provider"
value-ref="multitenantConnectionProvider"></entry>
<entry key="hibernate.show_sql" value="true"></entry>
<entry key="hibernate.use_sql_comments" value="true"></entry>
<entry key="hibernate.connection.charSet" value="UTF-8"></entry>
</map>
</property>
</bean>
Надеюсь, это поможет.