当前位置: 首页 > 面试题库 >

在运行时休眠多租户创建架构

傅浩漫
2023-03-14
问题内容

我正在使用hibernate 4和spring 4为Java
Web应用程序设置多租户支持。默认模式是在应用程序启动时创建和设置的。当不尝试支持多租户时,此架构可以正常工作。

现在,我需要为每个创建帐户的新租户创建一个架构。该模式可以简单地是通用模式的副本,因为它将遵循相同的格式。

如何在运行时创建与默认架构相同格式的新架构?似乎在实例化LocalSessionFactoryBean时创建了默认模式,因为这是我指定映射资源的地方。


问题答案:

我想出了解决我的问题的解决方案。我希望这对外面的人有用。

因此,主要问题归结为Hibernate的限制,即在多租户配置中在运行时为新客户端创建模式。

“ Hibernate在多租户环境中不支持自动模式导出。”

为了解决此限制(使用Spring),我的解决方案是创建一个新的LocalSessionFactoryBean,将其配置为不支持多租户。所以基本上我有两个LocalSessionFactoryBeans。

  1. 用于多租户会话的多租户LocalSessionFactoryBean
  2. 非多租户LocalSessionFactoryBean,用于使用spring文件中的配置为租户创建架构。

弹簧配置

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



 类似资料:
  • 问题内容: 我正在开发将来的多租户Web应用程序,它将需要支持数千个用户。该应用程序是在基于Java的Play之上构建的!使用JPA / Hibernate和postgreSQL的MVC框架。 我看了盖伊·纳尔(Guy Naor)关于在Rails中编写多租户应用程序的演讲,其中他谈到了几种多租户方法(数据隔离度随着列表的增加而降低): 每个客户都有一个单独的数据库 一个为每个客户提供单独的架构和表

  • 问题内容: 创建一个新的数据库架构,并创建一个不存在的数据库架构,并更新现有的数据库架构。如果我想检查数据库模式是否存在,并根据将要创建的数据库模式来检查,该如何实现。目前,我的配置是: 和HibernateEMSDao.java: 这是工作。什么配置可以帮助我实现这一目标?就像是: 检查ID = 1的用户是否存在 如果没有创建架构 感谢致敬。 问题答案: 您可以禁用该选项,检查条件(可能使用普通

  • 问题内容: 是否可以在运行时创建休眠的Entity类(带有注释)?它应该与也在运行时添加的表相关。重要的是,该实体应该对Hibernate可见。一般情况下是否可能,请您给我有关该问题的任何建议吗?我了解,反射是关键字,但需要更多的单词。问候。 问题答案: 在这种情况下,您可能希望在运行时以编程方式创建Hibernate Session Factory,传入您创建的新映射,并查看http://doc

  • 问题内容: 我正在尝试使Spring-Data JPA与Hibernate一起使用自定义的MultiTenantConnectionProvider。 我下面的配置中的所有内容似乎都可以正常工作。我的类被称为每次我尝试调用库方法。 主要问题是无法提供租户标识符。Spring-Data提供的Repository接口负责获取Hibernate Session。 有什么方法可以向Spring-Data提

  • 问题内容: 我有一个Java实体,其字段带有注解@Formula,在其中执行了一个SQL查询,其中包含Firebird数据库的某些特定功能。现在,我必须迁移到Oracle数据库,并且需要替换该@Formula中的SQL代码。有办法实现吗?我可以通过某种方式扩展Hibernate @Formula以便在运行时更改注释的值吗?谢谢 问题答案: 您可以实现这种稍微不同的方式。 您可以放置一个占位符并添加

  • 问题内容: 我想在MS SQL中使用hibernate模式创建一个对象,该表的名称为“ user”。这没用!。我认为此问题可能是由表/实体的名称引起的,用户是关键字。拥有名称为“ user”的表该怎么办? 问题答案: 我应该使用重音符号()。