Search code examples
springjpaproxy-classes

spring autowiring fails with @Transactional


I want to use @Transactional annotation in the save() method of UserService(concrete class) as follows:

@Service
public class UserService {

    @Transactional
    public Long save(User userCommand, BindingResult result) {
    ...
    }

}

I will use this service in MyRealm by autowiring.

public class MyRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;

}

However, it fails with the following error:

java.lang.IllegalArgumentException: Can not set n.r.c.s.user.UserService field n.r.c.s.realm.MyRealm.userService to com.sun.proxy.$Proxy48

Of course, it works if I remove the @Transational annotation.

My transaction manager setting is as follows:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

Please, let me know what's wrong with my code?

Do I need to set up something like proxy?


Solution

  • When proxying is enabled you need to use interfaces, not implementations.

    @Service
    public class UserService implements SomeInterface {
    
    @Transactional
    public Long save(User userCommand, BindingResult result) {
    ...
    }
    
    }
    
    
    public class MyRealm extends AuthorizingRealm {
    
    @Autowired
    private SomeInterface userService;
    
    }
    

    If you do not want to do this, you can always check your AOP config. you are probably doing proxy for a proxy somewhere.