Spring 3 @controller cannot enter a service object that has @Transactional

I am using Spring 3 MVC, I have a problem with object injection. I created a Controller object with @Controller . And I created a service object with an @Service object. I injected the service object into the controller using AutoWire. And I created a DAO object and injected it into the service object and tested the application, it works fine. Then I put @Transactional on the DAO, and then it worked fine. But when I put @Transactional in the service object, it gives me a problem. During deployment on the controller, it says like "

Failed to initialize context: org.springframework.beans.factory.BeanCreationException: Error creating bean with name "loginController": could not inject auto-notified dependencies; The nested exception is org.springframework.beans.factory.BeanCreationException: The autowire method failed: public void com.erudicus.controller.LoginController.setLoginService (com.erudicus.model.service.LoginServiceImpl); The nested exception is java.lang.IllegalArgumentException: argument type mismatch. "

Here is the code controller

 @Controller public class LoginController { private static Logger LOG = Logger.getLogger(LoginController.class); private LoginServiceImpl loginService = null; public LoginServiceImpl getLoginService() { return loginService; } @Autowired public void setLoginService(LoginServiceImpl loginService) { this.loginService = loginService; } @RequestMapping(value="/login" , method= RequestMethod.GET) public String login(Model model) { model.addAttribute(new Login()); return "login"; } @RequestMapping(value="/loginDetails", method=RequestMethod.POST) public ModelAndView create(@Valid Login login, BindingResult result) { } } 

Service object

 @Service public class LoginServiceImpl implements LoginService { private LoginDao loginDao = null; public LoginDao getLoginDao() { return loginDao; } @Autowired public void setLoginDao(LoginDao loginDao) { this.loginDao = loginDao; } @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public Login getUserDetails(String userId) { return getLoginDao().getUserDetails(userId); } } 

DAO

 @Service @Transactional(propagation = Propagation.MANDATORY) public class LoginDaoImpl extends SqlSessionDaoSupport implements LoginDao { @Transactional(readOnly = true, propagation = Propagation.MANDATORY) public Login getUserDetails(String userId) { } } 

In the configuration I specified

 <bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager" /> <!-- enable autowire --> <!-- enable transaction demarcation with annotations --> <tx:annotation-driven transaction-manager="txManager"/> <context:annotation-config/> 

Anyone can help

+4
source share
1 answer

Define the field as an interface, not a specific class. (So UserService instead of UserServiceImpl ). You can add the @Transactional annotation to a specific class - it will work.

The problem is that by default, spring uses the JDK proxies ( java.lang.reflect.Proxy ), which are proxies only. Your particular class is then used by the call handler, but you cannot use it.

If there is no interface, spring uses another method - CGLIB, which subclasses the target class to make a proxy.

You can use <aop:scoped-proxy /> to configure proxy ( proxy-target-class ) to bean.

+11
source

Source: https://habr.com/ru/post/1339193/


All Articles