【问题标题】:Add schema name dynamically in hibernate mapping file with spring使用spring在hibernate映射文件中动态添加模式名称
【发布时间】:2018-06-02 19:48:22
【问题描述】:

我在我的项目中使用 spring + hibernate + oracle。我将 LocalSessionFactoryBean 作为会话工厂对象,并将不同的 hbm.xml 文件映射到我的项目中。

我的配置如下:

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mappingResources">
            <list>
                <value>one.hbm.xml</value>
                <value>two.hbm.xml</value>
                <value>three.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">....</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.release_mode">after_transaction</prop>
                <prop key="hibernate.transaction.auto_close_session">true</prop>
                <prop key="hibernate.hbm2ddl.auto">none</prop>
            </props>
        </property>
    </bean>

现在我有三个映射文件,每个映射文件都引用不同的架构。因此,要映射架构名称,我可以在每个映射文件中提供名称,例如:

<hibernate-mapping schema="one">

但问题是我根据不同的环境有不同的架构名称。那么如何以编程方式对其进行配置。

【问题讨论】:

    标签: java spring hibernate hibernate-mapping


    【解决方案1】:

    我通过在构建映射时修改 spring 配置解决了这个问题。

    我通过扩展org.springframework.orm.hibernate4.LocalSessionFactoryBean 创建了一个自定义本地会话工厂,并添加了以下方法。

    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sessionFactoryBuilder) {
        try {
            sessionFactoryBuilder.buildMappings();
            Iterator<Table> iterator = getConfiguration().getTableMappings();
            while (iterator.hasNext()) {
                Table table = iterator.next();
                if (table.getSchema() != null && !table.getSchema().isEmpty()) {
                    table.setSchema(mySchemaName);
                }
            }
        } catch (Exception ex) {
            logger.error("Exception occurred while building mapping: ", ex);
        }
        return super.buildSessionFactory(sessionFactoryBuilder);
    }
    

    【讨论】:

      【解决方案2】:

      不要在休眠配置 xml 文件中提供模式名称。根据您不同的环境需求创建单独的 .properties 文件。并根据环境使用它们。 像这样的东西。。

      <session-factory>
          <!-- Database connection settings -->
          <property name="driverClassName" value="#{db['driverClassName']}"></property>
          <property name="url" value="#{db['url']}"></property>
          <property name="username" value="#{db['username']}"></property>
          <property name="password" value="#{db['password']}"></property>
      
      </session-factory>
      

      【讨论】:

      • 情况是我只有一个会话工厂和数据源,我有一个模式作为主模式,并从该主模式访问其他模式的表。
      • 您使用的是哪个数据库?
      • 我正在使用oracle数据库
      • 您可以在实体内部提供架构名称,它将适用于 oracle db
      【解决方案3】:
      you can provide the schema name inside the entity and it will work for oracle db Entity "Account" in schema "ABC" 
      @Entity
      @Table(name="ACCOUNT",schema="ABC")  
      class ACCOUNT{
      ...
      }
      Entity "CUSTOMER" in schema "XYZ"
      @Entity
      @Table(name="CUSTOMER",schema="XYZ")  
      class CUSTOMER{
      ...
      }
      

      【讨论】:

      • 这很好,但我不想在不同的环境(dev,qa)上使用硬编码作为模式名称是不同的。例如在本地,架构名称是 1,但在 qa 上是 one_1,我使用的是基于 xml 的休眠映射。
      • 你在用maven的投诉项目吗?如果是,您可以创建配置文件并定义您的条目。我建议专注于环境配置以及您的构建方式。你可以提供环境变量在你的代码中使用它们。
      • 我正在使用 gradle,但会尝试使用您建议的方式并更新相同的方式谢谢
      猜你喜欢
      • 2010-10-28
      • 2014-10-22
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多