如何在Spring中定义多个sessionfactory实例?

时间:2009-04-27 17:34:50

标签: java hibernate spring

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

这可能吗?我该怎么做呢?

4 个答案:

答案 0 :(得分:3)

您可以定义抽象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>

使用'abstract'属性可确保bean不会被实例化,并且它将仅用作模板。

此处有更多信息:link text

答案 1 :(得分:1)

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

有关详细信息,请参阅this question

this blog post关于Spring中的动态数据源路由。

答案 2 :(得分:0)

我不知道你现在的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>

然后你可以简单地用一个sessionFactory和另一个sessionFactory连接你的DAO:

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

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

答案 3 :(得分:0)

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

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

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