I am using Spring 3 MVC, I have a problem in injecting the Objects.
I created the Controller Object with the @Controller
. And I have created a Service Object with the @Service
Object. I injected the service object in the controller with AutoWire.
And I created the DAO Object, and injected in the Service Object, and Tested the application , it is running fine.
Then I put @Transactional
on DAO, then also it worked fine. But when I put the @Transactional
on service object,It is Giving me the problem. At the time of deploying , at the Controller it says as "
Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.erudicus.controller.LoginController.setLoginService(com.erudicus.model.service.LoginServiceImpl); 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/>
Any one can please help
Define the field to be an interface, rather than a concrete class. (So UserService
instead of UserServiceImpl
). You can add the @Transactional
annotation on the concrete class - it will work.
The problem is that by default spring uses JDK proxies (java.lang.reflect.Proxy
) which are interface-only proxies. Your concrete class is then used by the invocation handler, but you cannot cast to it.
If there is no interface, spring uses another method - CGLIB, which subclasses the target class in order to make the proxy.
You can use <aop:scoped-proxy />
to configure the proxying stragegy (proxy-target-class
) per bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With