On the importance of understanding the Spring contexts

31 August 2013, by Baptiste Autin

Lately, I had to work on a buggy application: all the annotations @Transactional, defined at the business level, seemed to be ineffective, in spite of the correct definition of a transactional manager in the main Spring context of the application.

I have to say that the annotated methods were all public (as this is a requirement with @Transactional and JDK proxies)

What the hell was going on?

 

In the file applicationContext.xml (= Web context), I did find the declaration of the JPA manager:

    
    
        
    

As well as the service beans of the application, detected by scan:

                               
       

So I expected the file myapplication-servlet.xml (= Spring MVC context) to define the controllers of the application.
But here is what I stumbled upon:

    

Instead of just scanning the MVC controllers (in foo.myapplication.controllers), we scanned the whole application! Therefore, the business beans were scanned a second time (note that this is not a problem for Spring).
But, like many other things in the Spring framework, the declarative support for transactions relies on AOP proxies, and AOP proxies are only valid in the Spring context where they are defined in. As a consequence, the declaration <tx:annotation-driven />, in the main Spring context, was ineffective in the MVC context.

The solution to my problem simply consisted in bounding the class scan, in myapplication-servlet.xml, to the sole controllers package:

    

Business beans and DAO beans are now defined in the main context, i.e. where the JPA manager is also defined.

 

Conclusion
The MVC Spring context should only contain the components of the MVC framework, and no business- or data-access-logic.
Not respecting this principle is not only a mistake from an architectural perspective, it is prone to erros that may stay hidden long.

Laisser une réponse

«     »