我正在开发一个多租户应用程序,这意味着我需要能够根据拥有请求用户配置文件的组织帐户来过滤 API 响应。在我们的模型中,这被称为
Tenant
。我有工作 Hibernate 过滤器,它让我可以控制结果查询的范围,以便“foo”的 tenantId
下的用户只能看到也属于 foo 的关联模型中的行。
我面临的挑战是,我必须在控制器方法的范围内启用此过滤器 - 因此我将代码放在关联模型服务的接触点处。这似乎是 Servlet 过滤器的候选者,但似乎不起作用。
为了实现,我向
enableFilter
服务添加了一个公共 @Transactional
方法,该服务使用其内部存储库引用来启用针对我的 Hibernate 会话的过滤器。然后我将 @Autowired
放入我的 servlet 过滤器中,这样我就可以获取与当前请求用户关联的租户并相应地启用 Hibernate 过滤器。
问题是,这行不通。看来 Hibernate 会话要么不活动,要么在实际服务执行任何工作之前重置。启用 servlet 过滤器后生成的查询不包括我的租户过滤。在我的服务中启用这些过滤器可以让我知道过滤器本身是正确的。我是否遗漏了什么,或者我是否必须在请求处理的食物链中进一步启用这些过滤器?
几天来我一直面临着同样的挑战。尝试了好几种方法,最后决定用这个方法解决。
我通过在 Filter 的
@Transactional
方法上添加 doFilter
注释使其工作(在 Spring boot 3 中)。
PS:我用了
org.springframework.transaction.annotation.Transactional
。
jakarta.transaction.Transactional
也有效。
首先,我尝试使用 AspectJ AOP 方法来启用我的休眠过滤器,这也有效,但我讨厌 AspectJ 的加载时间编织增加了我的应用程序的启动/实时重新加载延迟太多。所以我进一步研究并得出了这种轻量级的方法。