I asked this question but it is closed and i haven't get my answer exactly; Spring @Transactional annotation is not working in the provider class which is a subclass of AbstractUserDetailsAuthenticationProvider
And I read this answer; Spring - @Transactional - What happens in background?
They said something about internal method call and external method call. But this works in any controller or service. Why not in provider class which annotated as @Component? Why can't Spring or Hibernate open a session in provider class even with @Transactional annotation? Is this something about spring security? What is the difference?
Please go through the reference documentation
The following images shows a Conceptual view of calling a method on a transactional proxy:
Now with this information , a method annotated with @Transactional
will start a transaction only when the call to the method comes in through the proxy object of the class that has this annotated method. This call is mentioned as the external call by the experts in your previous question.
In case of your example ,
The implementation of abstract method AbstractUserDetailsAuthenticationProvider.retrieveUser() is called from AbstractUserDetailsAuthenticationProvider.authenticate() , which is a self invocation. This is what the experts mentions as internal call . Also note that the method authenticate()
is not @Transactional
Go through the documentation under the section Using Transactional
In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation (in effect, a method within the target object calling another method of the target object) does not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional. Also, the proxy must be fully initialized to provide the expected behavior, so you should not rely on this feature in your initialization code (that is, @PostConstruct).
In your provider class which is annotated with @Component
the call to the proxy reaches a method which is not annotated with @Transactional
and does a self-invocation or internal call to the method annotated with @Transactional
, which does not work as explained earlier
With the Controller or Service , the method annotated with @Transactional
is getting called first (external call) , which initiates a transaction . The code flow within the context of that method is in a transaction and all the subsequent methods are participating in that transaction and you do not see the - no Session
exception.
Hope this helps