I have a XAuthenticationProvider
class which extends AbstractUserDetailsAuthenticationProvider
abstract class. And in retrieveUser()
method, i want to return the user entity which is lazy loaded from UserSession
entity. When I put @Transactional
annotation on top of the overriden retrieveUser()
method, Hibernate.initialize()
threw LazyInitializationException
. But I put this annotation to the foo() method in another service(AService), it is working and proxy object successfully converted to entity.
Here is my provider class;
@Component
public class XAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
@Autowired
private AService aService;
@Override
@Transactional
public UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken token) throws AuthenticationException {
return aService.foo();
}
}
I inject the provider class in SecurityConfig like this;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private XAuthenticationProvider xAuthenticationProvider;
@Bean
@Override
public AuthenticationManager authenticationManager() {
return new ProviderManager(Collections.singletonList(xAuthenticationProvider));
}
public TokenFilter tokenFilter() {
TokenFilter filter = new TokenFilter(new OrRequestMatcher(
new AntPathRequestMatcher("*")
));
filter.setAuthenticationManager(authenticationManager());
return filter;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// REMOVED THIS PART FOR SECURITY REASONS
http.addFilterBefore(tokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
And this is the foo()
method in AService
which is annotated by @Service
;
//@Transactional
public User foo() {
UserSession userSession = userSessionRepository.findByStatus(Status.ACTIVE);
if(userSession!=null) {
User user = userSession.getUser(); // Lazy loaded
Hibernate.initialize(user); // Error is thrown from here
return user;
}
return null;
}
Error thrown is;
org.hibernate.LazyInitializationException: could not initialize proxy [com.turkcell.masrafim.persistence.entity.User] - no Session
So here is my question, i know that Hibernate.initialize()
method must be called in an unclosed session to initialize the lazy loaded proxy object, and because of that, I put @Transactional
annotation which is org.springframework.transaction.annotation.Transactional
on top the method. But why is this annotation is not working on provider class which is a @Component
and why is it working in upper level @Service
class? What is the difference?