Add way to enable Session filter for Hibernate 5+ [SPR-16518]
See original GitHub issueDominik Bartholdi opened SPR-16518 and commented
in the context of #5615, setFilterName and setFilterNames methods have been added to HibernateAccessor to support enabling Hibernate Filters for Hibernate 3. Unfortunate there seems no equivalent way to enable Hibernate Filters when using Spring Data Repositories with Hibernate 5.
Sure, I can create a pointcut that matches all repositories:
@Pointcut("execution(* org.springframework.data.repository.Repository+.*(..))")
public void activateTenantFilter() throws Throwable {
Optional<Long> tenantId = TenantUtil.getCurrentTenantId();
tenantId.ifPresent(id -> {
Session session = entityManager.unwrap(Session.class);
Filter filter = session.enableFilter("TENANT_FILTER");
filter.setParameter("tenantId", id);
});
}
But this means the aspect is executed way to many times - e.g. if I have a service calling multiple repository methods.
Another way would be to define a custom annotation (e.g. @EnableTenantFilter) and annotate service methods with it to enable the filter based on a Pointcut specific for this Annotation and do the same as in above, but this could lead to the same issue as above.
A nicer way would be to define a Pointcut for org.hibernate.SessionBuilder.openSession, but as SessionBuilder is not exposed as a Bean, but this requires Load Time Weaving 😦
@AfterReturning(pointcut = "execution(* org.hibernate.SessionBuilder.openSession(..))", returning = "session")
public void forceFilter(JoinPoint joinPoint, Object session) {
...
Filter filter = session.enableFilter("TENANT_FILTER");
filter.setParameter("tenantId", id);
}
Also DATACMNS-293 would provide a way to implement such a filter (even independent of Hibernate), but it does not seem to be merged anytime soon 😦
A way to ease this, would be some kind of a listener that is called whenever a new Hibernate Session is created and allows me to enable the Filter based on my criteria at that point. An important point is that I need to be able to pass parameters to the filter, otherwise it does not make a lot of sense.
Maybe I have missed something and this already exists…
No further details from SPR-16518
Issue Analytics
- State:
- Created 6 years ago
- Reactions:7
- Comments:10
Top Related StackOverflow Question
Hi @jofatmofn, I have implemented and documented this in a standalone Spring Boot application except the TenantId is applied through a received JWT token. But the same concept can be applied with your tenantId. https://github.com/M-Devloo/Spring-boot-auth0-discriminator-multitenancy
This project is built to tackle the discriminator based multi tenancy problem.
Thanks @bugy, I have raised a SO question for my issue at https://stackoverflow.com/questions/62387223/why-createentitymanager-is-called-before-my-rest-controller-method.