如何使用Spring Data Jpa启用Multitenancy

时间:2017-05-23 12:58:41

标签: spring hibernate spring-mvc spring-data spring-data-jpa

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

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

}

和下面的服务,

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

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

尝试的解决方案:

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")
}

休眠过滤器听起来像是一种很有前途的方法,但我试图投入一个有效的解决方案。我想知道是否有一种替代方法可以在Spring数据内部用于查询数据的会话中启用hibernate过滤器。

1 个答案:

答案 0 :(得分:4)

我发表了关于Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres的博客,即使我采用每个租户方法的数据库,DISCRIMINATOR(用于指定不同租户的一个或多个表列)方法,您使用最多 - 可能需要更少配置。

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