lars
lars

Reputation: 670

Bean gets no transactional proxy on ContextRefreshedEvent in Spring 4.2.5

I have a bean (SettingService) which is decorated with the @Transactional annotation and injected into another bean where this bean is invoked on the context refreshed event.

public class DefaultConfigManager
    implements ApplicationListener<ContextRefreshedEvent>, ConfigManager {

    @Autowired
    private SettingService service;

    @Override
    public void onApplicationEvent( ContextRefreshedEvent event ) {
        System.out.println( "Proxy: " + AopUtils.isJdkDynamicProxy( service ) );
        String key = service.getSystemSetting( "KEY" );
    }

Transactions work generally well and the method above works as expected in Spring 4.1.9, where the println indicates that the SettingService bean is a dynamic JDK proxy (for transaction handling).

Now after upgrading to Spring 4.2.5 this suddenly starts to throw the following error:

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread

at org.springframework.orm.hibernate4.SpringSessionContext. currentSession(SpringSessionContext.java:134)

at org.hibernate.internal.SessionFactoryImpl. getCurrentSession(SessionFactoryImpl.java:993)

and the println indicates that the SettingService is no longer a proxy / has been decorated, meaning that no transactions will be initiated.

According to the Spring documentation, at the time of ContextRefreshedEvent being published, all beans and post-processors should be finished.

A Hibernate transaction manager is configured in the app context, the tx:annotation-driven element is in place, the @Transactional annotation is put on the implementation (not the interface), there are no circular dependencies in the system. Hibernate version: 4.2.20.Final.

Does this ring a bell with anyone? Are there any typical reasons for why beans no longer should be proxied with transactions on ContextRefreshedEvent in Spring 4.2? Any common mistakes or changes between Spring 4.1 and 4.2 to be aware of?

Upvotes: 4

Views: 768

Answers (1)

clockrun
clockrun

Reputation: 21

I got same problem as you have. My workaround is, put @Transactional annotation on class level rather than method level.

Upvotes: 2

Related Questions