I am using springboot 2.7.1 I have a hibernate filter defined on my entities which I am injecting using aspect for all repositories which implements my TenantableRepository.

The issue is that the filter is not getting injected in the repository calls executed within CompletetableFuture method. But filter is getting injected properly outside it. I understand that the threads are different but aspect is being called both the times though.

I want the filter to get enabled from all flows. API or async processes.

Here is the Aspect I have defined to work on all TenantableRepositories' methods starting with find.

@Aspect
@Component
@Slf4j
public class TenantFilterAspect {

    @PersistenceContext
    private EntityManager entityManager;

    @Before("execution(* com.demo.repository.TenantableRepository+.find*(..))")
    public void beforeFindOfTenantableRepository() {
        log.info("Called aspect");
        entityManager
                .unwrap(Session.class)
                .enableFilter(Tenantable.TENANT_FILTER_NAME)
                .setParameter(Tenantable.TENANT_COLUMN, TenantContext.getTenantId());
    }
}

I have a controller to test the flow. Here I am making 2 repository calls. One in main thread and one under async CompletetableFuture method.

import org.springframework.beans.factory.annotation.Autowired;

@RestController
@Slf4j
@RequestMapping(value = "/v1/api/test", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public class TestController {

    @Autowired
    MyEntityRepository myEntityRepository;

    @RequestMapping(value = "/aysnc", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE)
    public @ResponseBody
    ResponseEntity<APIResponse> testAsync(HttpServletRequest httpServletRequest) throws InterruptedException {
        Optional<MyEntity> entity = myEntityRepository.findByFirstName("Firstname");
        if(!entity.isEmpty()){
            log.info("1. Main: found entity:{}",entity.get());
        }
        CompletableFuture.runAsync(this::callAsyncMethod);
        return ResponseEntity.status(HttpStatus.OK)
                .body("Ok");
    }

    public void callAsyncMethod() {
        Optional<MyEntity> entity = myEntityRepository.findByFirstName("Firstname");
        if(!entity.isEmpty()){
            log.info("2. Async: found entity:{}",entity.get());
        }
    }

}

The issue is that the filter is not getting injected in the repo call under async CompletetableFuture method callAsyncMethod(). But filter is getting injected properly in first repo call before async method. I understand that the threads are different but aspect is being called both the times. I get the log printed but the filter is still not enabled.

What am I doing wrong here?

Edit: Adding link to the stackoverflow question for the same https://stackoverflow.com/questions/77149468/hibernate-filter-not-getting-applied-within-async-process

It seems that we need to use Transactional annotation for the method called in async manner on separate thread.

Comment From: mdeinum

This was originally a question on StackOverflow -> https://stackoverflow.com/questions/77149468/hibernate-filter-not-getting-applied-within-async-process?noredirect=1#comment136009652_77149468

Comment From: saloniudani

Yes you are right @mdeinum . But since I could not get answers I thought to post here. But now I see you have replied. I have further questions on the same if you could help. Thanks in advance!

Comment From: sbrannen

Thanks for getting in touch, but it feels like this is better suited to the aforementioned discussion on Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.