Why is Spring JPA deleting the ServletRequestAttributes?

329 Views Asked by At

In order to copy the Spring RequestAttributes into an @Async thread, I have implemented a TaskDecorator bean, based on How to enable request scope in async task executor.

@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean
    public TaskDecorator taskDecorator() {
        return runnable -> {
            RequestAttributes context = RequestContextHolder.getRequestAttributes();
            return () -> {
                try {
                    RequestContextHolder.setRequestAttributes(context);
                    runnable.run();
                } finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            };
        };
    }
}

This approach works well, until JPA is added to the @Async thread. I have an asynchronous service method, invoked by a controller that takes an authorization header.

@Async
public void logAuthToken() {
    System.out.println(">>> authToken before Repo call: " + getAuthToken());
    repo.findAll();
    System.out.println(">>> authToken after Repo call: " + getAuthToken());
}

private String getAuthToken() {
    return Optional.ofNullable(RequestContextHolder.getRequestAttributes())
            .map(ServletRequestAttributes.class::cast)
            .map(ServletRequestAttributes::getRequest)
            .map(request -> request.getHeader(AUTHORIZATION))
            .orElse("No Authorization Token in this Context!");
}

The TaskDecorator successfully populates the RequestAttributes when the thread starts; but after a JPA call, the attributes are gone.

>>> authToken before Repo call: my-auth-token
>>> authToken after Repo call: No Authorization Token in this Context!

The repo is an empty CrudRepository interface. A full working example is in github.

Why is JPA apparently deleting the RequestAttributes and how can I prevent it from doing that?

0

There are 0 best solutions below