0

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?

elif erdil
  • 39
  • 7

1 Answers1

0

Please go through the reference documentation

The following images shows a Conceptual view of calling a method on a transactional proxy:

enter image description here

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

R.G
  • 6,436
  • 3
  • 19
  • 28