使用Hibernate / JPA的多租户共享连接池中的错误

时间:2019-07-11 07:44:24

标签: hibernate spring-batch jhipster multi-tenant connection-pool

使用 MultiTenantConnectionProvider 实现了共享连接池

在getConnection()中,我使用了connection.createStatement()。execute(“ USE” + tenantIdentifier +“;” );

但是它只能在第一次正常工作 ,如果我第一次通过Schema3,它将运行良好,但是在运行时,如果通过Schema2,它将仍然指向相同的shcema3。

import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Stoppable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;

/**
 * Created by AdamS on 2015-04-02.
 */
public class SchemaMultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider, ServiceRegistryAwareService, Stoppable {

    private final Logger log = LoggerFactory.getLogger(SchemaMultiTenantConnectionProviderImpl.class);

/*    @Autowired
    @Qualifier("HikariDataSource")*/
    DataSource dataSource;

    @Override
    public Connection getAnyConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
        /*try {
            connection.createStatement().execute("USE jhipster;");
        } catch (SQLException e) {
            throw new HibernateException("Could not alter JDBC connection to specified schema [public]", e);
        }*/
        connection.close();
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        log.warn("Get Connection for Tenatd is:" + tenantIdentifier);
        final Connection connection = getAnyConnection();
        try {
//            connection.setCatalog(tenantIdentifier);
            connection.setSchema(tenantIdentifier);
            /*connection.setSchema(tenantIdentifier);
            connection.createStatement().execute("USE " + tenantIdentifier + ";");*/

            connection.createStatement().execute("USE "+ tenantIdentifier + ";");
//            connection.setCatalog(tenantIdentifier);
            connection.setSchema(tenantIdentifier);

        } catch (SQLException e) {
            throw new HibernateException("Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]", e);
        }
        return connection;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
        try {
            connection.createStatement().execute("USE " + tenantIdentifier + ";");
        } catch (SQLException e) {
            throw new HibernateException("Could not alter JDBC connection to specified schema " + tenantIdentifier, e);
        }
        connection.close();
    }

    @Override
    public boolean supportsAggressiveRelease() {
        return false;
    }

    @Override
    public boolean isUnwrappableAs(Class unwrapType) {
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> unwrapType) {
        return null;
    }

    @Override
    public void injectServices(ServiceRegistryImplementor serviceRegistry) {
        Map lSettings = serviceRegistry.getService(ConfigurationService.class).getSettings();
        DataSource localDs = (DataSource) lSettings.get("hibernate.connection.datasource");
        dataSource = localDs;
    }

    @Override
    public void stop() {
        try {
            dataSource.getConnection().close();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
        }
    }```

I want to switch schema at runtime, to use multi-tenant base schema with a shared connection pool.

0 个答案:

没有答案