Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing the EntityManager in an @Aspect for a JpaRepository

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?

like image 683
n_l Avatar asked Sep 13 '25 20:09

n_l


1 Answers

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());
    }
}
like image 141
clevertension Avatar answered Sep 16 '25 10:09

clevertension