Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
792 views
in Technique[技术] by (71.8m points)

hibernate - How to enable Multitenancy with Spring Data Jpa

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...