4

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

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
Kumar
  • 41
  • 1
  • 2
  • I asked a similar question if it helps: http://stackoverflow.com/questions/2713033/autowire-strange-problem – Javi Feb 10 '11 at 16:01

1 Answers1

11

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.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Yes, It Worked, Thank you for that, But I have another question, Anotation are not inherited, And my service interface is not annoted with @transaction, I annoted in the concerete class as @Transaction, will the transactions is loaded by the service, when a controller some operations on Service which has a Transaction set. And also please explain what is problem with my earlier version of the code. – Kumar Feb 10 '11 at 13:45
  • I was having a similar problem and your answer and explanation helped me out, Thanks! – Paul Parker Jun 16 '11 at 17:44
  • Helped me out too. Thanks !!! I though I could quickly autowire dao's three levels deep w/o the use of interfaces. It worked for two levels. At the third it started working with proxies. Why ... mystery. :-) – Jan Goyvaerts Dec 21 '11 at 13:11