我想在spring应用程序中有多个Hibernate SessionFactories,除了DataSource之外,它们都具有相同的配置。理想情况下,我会按名称获取特定的SessionFactory。我需要能够根据运行时状态执行此操作,并且无法确定在应用程序启动时我将需要哪些会话工厂。基本上,我需要一个SessionFactoryTemplate或类似的东西。
这可能吗?我该怎么做呢?
答案 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支持内部,这是我尝试过的,但后来取消了第一种方法。我确信它可以通过适度的努力来完成,但之前的解决方案已经为我们完成了工作。