복붙노트

[SPRING] 런타임 동안 Hibernate 멀티 테넌시 생성 스키마

SPRING

런타임 동안 Hibernate 멀티 테넌시 생성 스키마

최대 절전 모드 4 및 4를 사용하여 Java 웹 응용 프로그램에 대한 다중 사용자 지원을 설정 중입니다. 기본 스키마는 응용 프로그램이 시작될 때 만들어지고 설정됩니다. 이 스키마는 멀티 테넌시를 지원하지 않을 때 잘 작동합니다.

지금해야 할 일은 계정을 만드는 각각의 새 테넌트에 대한 스키마를 만드는 것입니다. 이 스키마는 동일한 형식을 따르므로 공통 스키마의 복사본 일 수 있습니다.

런타임 중에 기본 스키마와 동일한 형식을 따르는 새 스키마를 만들려면 어떻게해야합니까? LocalSessionFactoryBean은 매핑 리소스를 지정하기 때문에 인스턴스화 될 때 기본 스키마가 만들어지는 것으로 보입니다.

해결법

  1. ==============================

    1.나는 내 문제를 해결할 수있는 해결책을 찾았다. 나는 누군가에게 유용하기를 바란다.

    나는 내 문제를 해결할 수있는 해결책을 찾았다. 나는 누군가에게 유용하기를 바란다.

    그래서 주요 문제점은 멀티 테넌트 구성 중에 런타임 동안 새로운 클라이언트에 대한 스키마를 생성하는 Hibernate 제한에 달려 있습니다.

    이 제한 (Spring 사용)을 해결하기위한 나의 해결책은 멀티 테넌시를 지원하지 않도록 구성된 새로운 LocalSessionFactoryBean을 만드는 것이 었습니다. 그래서 기본적으로 두 개의 LocalSessionFactoryBeans가 있습니다.

    스프링 구성

    <!-- 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>
    

    스키마를 만드는 데 사용되는 코드

    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;
    }
    

    이 코드의 _configuration은 Non-Multi-Tenant LocalSessionFactoryBean

  2. ==============================

    2.eclipseLink를 사용하여 문제점을 해결할 수 있습니다. 다음은 몇 가지 유틸리티 링크입니다. https://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant 과 http://www.javacodegeeks.com/2012/02/sneak-peak-at-java-ee-7-multitenant.html 또는 당신이 최대 절전 모드를 사용하기를 원한다면 이것에 대해 살펴보십시오. http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html 최대 절전 모드의 멀티 테넌시에 대한이 예제는 https://gist.github.com/dipold/5700724 및 http://www.devx.com/Java/Article/47817입니다.

    eclipseLink를 사용하여 문제점을 해결할 수 있습니다. 다음은 몇 가지 유틸리티 링크입니다. https://wiki.eclipse.org/EclipseLink/Examples/JPA/Multitenant 과 http://www.javacodegeeks.com/2012/02/sneak-peak-at-java-ee-7-multitenant.html 또는 당신이 최대 절전 모드를 사용하기를 원한다면 이것에 대해 살펴보십시오. http://docs.jboss.org/hibernate/orm/4.1/devguide/en-US/html/ch16.html 최대 절전 모드의 멀티 테넌시에 대한이 예제는 https://gist.github.com/dipold/5700724 및 http://www.devx.com/Java/Article/47817입니다.

  3. from https://stackoverflow.com/questions/28633759/hibernate-multi-tenancy-create-schema-during-runtime by cc-by-sa and MIT license