如何使用Spring Data Jpa启用多租户 [英] How to enable Multitenancy with Spring Data Jpa
问题描述
背景:我正在构建一个Multitenant SaaS应用程序,并选择了单一数据库,共享架构作为多租户方法。每个表都有一个鉴别器列tenantId来隔离租户数据。我使用Spring引导作为应用程序框架,并利用Hibernate的弹簧数据jpa作为JPA提供程序。我非常喜欢Spring数据帮助消除样板代码的方式,并且目前已经编码了如下所示的存储库:
@Repository
public interface UserRepository扩展JpaRepository< User,Long> {
}
和服务如下,
public class UserService {
@Autowired
private UserRepository userRepo;
public User getUser(){
User user = userRepo.findOne(id);
问题陈述:我想获取用户,我想要获取特定组织的用户。我想知道如何添加租户标准,我不想编写自定义存储库实现,因为它会引入样板代码。
解决方案尝试: Hibernate Interceptor - onPrepareStatememt:这是没用的,因为sql是一个字符串,我不想进行字符串操作。
$ b$ b ii)使用Spring AOP启用Hibernate过滤器:使用@Filter注释实体并尝试在会话中设置过滤器。这不起作用,因为方面永远不会被调用。
@AfterReturning(pointcut =execution(* org.hibernate.jpa。 (会话)会话;内部.EntityManagerImpl.OpenSession(..)),返回=会话)
public void forceFilter(JoinPoint joinPoint,Object session){
Session hibernateSession =
session.enableFilter(tenantFilter)
}
休眠过滤声音就像一个有前途的方法,但我有一种尝试投入工作解决方案的墙壁。我想知道是否有其他方法可以在会话中启用Spring数据在内部用来查询数据的hibernate过滤器。
我已经发布了有关使用Spring Boot,JPA,Hibernate和Postgres的多租户应用程序,即使我使用DB租用方法, DISCRIMINATOR
(看看 CurrentTenantIdentifierResolver <一个或多个用于指定不同租户的表列(最多可能需要更少的配置)。 / code>实现( TenantDvdRentalIdentifierResolverImpl.java ), DvdRentalMultiTenantInterceptor.java
Spring MVC
拦截器和 DvdRentalTenantContext.java ,它使用 ThreadLocal
存储/传递tenantId。
Background : I am building a Multitenant SaaS app and have chosen single database, shared schema as the Multitenancy approach. Every table has a discriminator column "tenantId" to isolate the tenant data. I am using spring boot as the application framework and leveraging spring data jpa for the data layer with Hibernate as the JPA provider. I really like the way spring data helps in eliminating boilerplate code and have currently coded the respositories like below,
@Repository
public interface UserRepository extends JpaRepository<User,Long>{
}
and services like below,
public class UserService{
@Autowired
private UserRepository userRepo;
public User getUser(){
User user = userRepo.findOne(id);
}
}
Problem Statement: When i want to get user, i want to get the user for a particular org. I am wondering how do i add the tenant criteria, i do not want to write custom repository implementations as that will introduce boilerplate code.
Solutions Attempted:
i) Hibernate Interceptor - onPrepareStatememt : This is not useful as the sql is a string and i do not want to do string manipulation.
ii)Enabling Hibernate Filters with Spring AOP: Annotated entity with @Filter and tried setting the filter in session. This does not work as the aspect is never invoked.
@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")
}
The hibernate filters sounds like a promising approach but i have kind of hit the wall trying to put in a working solution. I would like to know if there is an alternate approach to enable the hibernate filter in the session that Spring data uses internally to query the data.
I have blogged about Multi-tenant applications using Spring Boot, JPA, Hibernate and Postgres and even though I took the DB per tenant approach, the DISCRIMINATOR
(One or multiple table columns used to specify different tenants) approach you are using most-likely requires less configuration.
Take a look at the CurrentTenantIdentifierResolver
implementation (TenantDvdRentalIdentifierResolverImpl.java), the DvdRentalMultiTenantInterceptor.java Spring MVC
interceptor and DvdRentalTenantContext.java that uses the ThreadLocal
to store / pass the tenantId.
这篇关于如何使用Spring Data Jpa启用多租户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!