I've been trying to follow the advice from 1, to implement discriminator column based multi-tenancy using Hibernate interceptors and filters in Spring Boot 2.0.5. So far the Interceptor is working, however I want to apply the Hibernate filter directly on Spring Data JPA Repositories. The aspect I wrote looks like this:
@Aspect
@Component
public class TenantAwareRepositoryAspect {
@Autowired
private EntityManager entityManager;
@Before("execution(* com.example.tenant.jpasupport.TenantAwareRepository+.*(..))")
public void before(JoinPoint joinPoint){
entityManager
.unwrap(Session.class)
.enableFilter(TENANT_FILTER_NAME)
.setParameter(TENANT_ID_PROPERTY_NAME, TenantHolder.getTenantId());
}
}
I then add the TenantAwareRepository
as a marker interface to the repositories that contain Tenant-scoped entities.
Now: My tests of the repositories using the @DataJpaTest annotation run through just fine, but when I start the app and try to fetch some data I am getting a IllegalStateException
with message "No transactional EntityManager available". I have an @EnableTransactionManagement
on my app configuration.
I am guessing I need to access the excact EntityManager that is used in the generated Spring Data Repository, but how do I get that in the aspect?
try to inject EntityManagerFactory instead of EntityManager
@Aspect
@Component
public class TenantAwareRepositoryAspect {
@Autowired
private EntityManagerFactory entityManagerFactory;
@Before("execution(* com.example.tenant.jpasupport.TenantAwareRepository+.*(..))")
public void before(JoinPoint joinPoint){
EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory)
.unwrap(Session.class)
.enableFilter(TENANT_FILTER_NAME)
.setParameter(TENANT_ID_PROPERTY_NAME, TenantHolder.getTenantId());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With