打开sessionInViewInterceptor/Filter来处理多个SessionFactories

问题描述 投票:0回答:2

我们正在开发一个多租户应用程序,每个租户都有单独的架构。

我们每个架构都使用一个

SessionFactory
,无需使用
OpenSessionInViewFilter
即可正常工作。

我们希望将 Spring

TransactionManager
OpenSessionInViewFilter
一起使用。

我们可以找到一些参考来自定义 OpenSessionInViewFilter 来处理多个

SessionFactories
(通过覆盖
lookupSessionFactory
方法),但它对我们不起作用,因为我们需要从 DAO 引用此 Filter。

因此,我们计划使用

OpenSessionInViewInterceptor
,它可以从其他 spring beans (DAO) 访问,但没有找到一种方法来自定义它以基于 TenantId 查找
SessionFactory

我们使用 Hibernate 3.2.5 和 Spring-2.5.6

java hibernate spring
2个回答
0
投票

要访问 DAO 中的过滤器,您可以将过滤器定义为 bean 并使用

DelegatingFilterProxy
将此 bean 注册为过滤器:

bean定义:

<bean id="openEntityManagerInViewFilter" class="org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter">
  <property name="entityManagerFactoryBeanName" value="entityManagerFactory"/>
</bean>

web.xml 部分:

<filter>
  <filter-name>openEntityManagerInViewFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>openEntityManagerInViewFilter</filter-name>
  <url-pattern>/</url-pattern>
</filter-mapping>

0
投票

我正在按照你说的做,而且有效。我在 dao 中有 2 个会话工厂(对我来说:主数据库和副本)。自定义 OSIV 过滤器(扩展 spring OpenSessionInViewFilter),并重载

lookupSessionFactory
。我可以确定使用哪个会话工厂,甚至可以基于 url 端点路径。

确保所有 dao 调用都使用与 OSIV 打开会话的会话工厂相匹配的会话工厂。您可以在

OpenSessionInViewFilter.openSession
SessionFactoryImpl.getCurrentSession
中设置断点,并确保
SessionFactory
指针 ID 匹配。

我发现

@Transactional
注释不需要指定备用transactionManager。

我设置了web.xml:

  <filter>
    <description></description>
    <display-name>hibernateSessionFilter</display-name>
    <filter-name>hibernateSessionFilter</filter-name>
    <filter-class>com.companyname.dao.impl.CustomOpenSessionInViewFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hibernateSessionFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

CustomOpenSessionInViewFilter
扩展
OpenSessionInViewFilter
并重载
lookupSessionFactory(request)
。它返回
SessionFactory

我的 applicationContext.xml 有第二组 bean:dataSource、sessionFactory 和 transactionManager。 2 个会话工厂被注入到 dao 基类中。

这 2 个会话工厂的目的是向副本发送一些只读流量,以减少主数据库的负载。

Spring使用

SpringSessionContext
(有一些*SessionContext类可以使用)并且具有与事务同步的逻辑。
SessionFactory.getCurrentSession()
致电
SpringSessionContext.currentSession()
TransactionSynchronizationManager
使用静态线程局部来存储状态。

我还在

Transactional
中找到了一个断点,它告诉我事务管理器名称和
Transactional
注释所在的方法。 (
TransactionAspectSupport
:345)(也尝试断点
TransactionInterceptor
并查看调用堆栈)

© www.soinside.com 2019 - 2024. All rights reserved.