【问题标题】:How can I define multiple sessionfactory instances in Spring?如何在 Spring 中定义多个 sessionfactory 实例?
【发布时间】:2023-03-22 01:05:02
【问题描述】:

我想在 Spring 应用程序中拥有多个 Hibernate SessionFactories,除了 DataSource 之外,它们都具有相同的配置。理想情况下,我会按名称获取特定的 SessionFactory。我需要能够根据运行时状态执行此操作,并且无法确定在应用程序启动时我需要哪些会话工厂。基本上,我需要一个 SessionFactoryTemplate 或类似的东西。

这可能吗?我该怎么做?

【问题讨论】:

  • 也许将您的问题更改为“如何使用 Spring 在运行时定义和动态切换多个 SessionFactory 实例?”这更好地反映了您的问题(将编辑,还没有足够的分数)。

标签: java hibernate spring


【解决方案1】:

您可以定义一个抽象 bean 并使用 bean 继承。这意味着您将拥有一个用作模板的 bean 定义,并且您可能有多个 bean 只是复制父 bean 设置的属性。

这是一个例子:

<bean id="abstractSessionFactory" abstract="true"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="mappingResources">
      <list>
        <value>product.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.HSQLDialect
      </value>
    </property>
</bean>

<bean id="mySessionFactory" parent="abstractSessionFactory">
    <property name="dataSource" ref="myDataSource"/>
    ...
</bean>

<bean id="mySessionFactory2" parent="abstractSessionFactory">
    <property name="dataSource" ref="myDataSource2"/>
    ...
</bean>

使用“抽象”属性可以确保 bean 不会被实例化,它只会被用作模板。

更多信息在这里:link text

【讨论】:

    【解决方案2】:

    您确定需要多个 SessionFactories 吗?如果所有映射/配置都相同,并且您只有多个相同的数据库(例如,在多租户应用程序中?),那么有一个连接到动态提供适当数据库连接的 DataSource 的 SessionFactory 怎么样?

    更多详情请见this question

    this blog post 在 Spring 中动态数据源路由。

    【讨论】:

    • 嗨。映射相同,但指向不同的架构/数据库。
    【解决方案3】:

    我不知道你当前的 bean 定义现在是什么样子,但你不会只是......定义第二个 SessionFactory 吗?

    <bean id="mySessionFactory1" 
       class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource1"/>
        <property name="mappingResources">
          <list>
            <value>product.hbm.xml</value>
          </list>
        </property>
        <property name="hibernateProperties">
          <value>
            hibernate.dialect=org.hibernate.dialect.HSQLDialect
          </value>
        </property>
    </bean>
    
    <bean id="mySessionFactory2"
       class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource2"/>
        ...
    </bean>
    

    然后您可以简单地将您的 DAO 与一个 sessionFactory 与另一个连接起来:

    <bean id="myProductDao" class="product.ProductDaoImpl">
      <property name="sessionFactory" ref="mySessionFactory1"/>
    </bean>
    
    <bean id="myCompanyDao" class="product.ProductDaoImpl">
      <property name="sessionFactory" ref="mySessionFactory2"/>
    </bean>
    

    【讨论】:

    • 我已经澄清了我的描述,以解释为什么它不是正确的答案。不过谢谢!
    • 您好正在考虑这个问题,但是您将如何实例化不同的 sessionfactories。
    【解决方案4】:

    我不知道使用 Spring 解决问题的简单方法。

    但是,您可以使用 Hibernate 拦截器,前提是可以通过一个主/管理数据库连接访问您的特定数据库/数据源。 This blog post 详细解释了如何,但其要点是动态替换 Hibernate 生成的 SQL 语句中的表名,用限定名称标识不同的数据库。这相对容易理解和维护,并且在我公司的多租户设置中运行良好。

    除此之外,您可以尝试编写自己的TransactionManager,使用HibernateTransactionManager 作为起点,添加对使用多个会话工厂的支持。但是,这意味着您必须真正深入了解 Spring ORM 支持内部,这是我尝试过的,但后来放弃了第一种方法。我确信它可以通过适度的努力来完成,但之前的解决方案已经为我们完成了这项工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-04
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 2016-05-04
      相关资源
      最近更新 更多