如何使用 Spring Data Jpa 启用多租户

Pra*_*een 2 spring hibernate spring-mvc spring-data spring-data-jpa

背景:我正在构建一个多租户 SaaS 应用程序,并选择了单一数据库、共享架构作为多租户方法。每个表都有一个鉴别器列“tenantId”来隔离租户数据。我使用 spring boot 作为应用程序框架,并使用 spring data jpa 作为数据层,Hibernate 作为 JPA 提供程序。我真的很喜欢 spring 数据有助于消除样板代码的方式,并且目前已经编写了如下所示的存储库,

@Repository
public interface UserRepository extends JpaRepository<User,Long>{

}
Run Code Online (Sandbox Code Playgroud)

和如下服务,

public class UserService{
    @Autowired
    private UserRepository userRepo;
    public User getUser(){
        User user = userRepo.findOne(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题陈述:当我想获取用户时,我想获取特定组织的用户。我想知道如何添加租户标准,我不想编写自定义存储库实现,因为这会引入样板代码。

尝试的解决方案:

i) Hibernate Interceptor - onPrepareStatememt :这没有用,因为 sql 是一个字符串,我不想进行字符串操作。

ii) 使用 Spring AOP 启用 Hibernate 过滤器:使用 @Filter 注释实体并尝试在会话中设置过滤器。这不起作用,因为从不调用方面。

@AfterReturning(pointcut = "execution(* org.hibernate.jpa.internal.EntityManagerImpl.OpenSession(..))", returning = "session")
public void forceFilter(JoinPoint joinPoint, Object session) {

    Session hibernateSession = (Session) session;
    session.enableFilter("tenantFilter")
}
Run Code Online (Sandbox Code Playgroud)

休眠过滤器听起来像是一种很有前途的方法,但我在尝试提供可行的解决方案时遇到了麻烦。我想知道是否有替代方法可以在 Spring 数据内部用于查询数据的会话中启用休眠过滤器。

oot*_*ero 6

我在博客上写过关于使用 Spring Boot、JPA、Hibernate 和 Postgres 的多租户应用程序,即使我采用了每个租户的 DB 方法,您使用的DISCRIMINATOR(用于指定不同租户的一个或多个表列)方法最有可能需要更少配置。

看看在CurrentTenantIdentifierResolver实现(TenantDvdRentalIdentifierResolverImpl.java),该DvdRentalMultiTenantInterceptor.java Spring MVC拦截和DvdRentalTenantContext.java使用该ThreadLocal存储/传递tenantId。