Search code examples
javaspringspring-mvclombokspring-annotations

@AllArgsConstructor not working with spring bean


I am having the class like below

@Controller
@RequestMapping(value = "/test")
@AllArgsConstructor
public class TestController {

    @Qualifier("userDAO")
    private final Test testDAO;

} 

Below is my bean registration

<bean id="userDAO" class="com.test.dao.TestImpl"
      p:sqlSessionFactory-ref="testSqlSessionFactory" />

when I run my app got error like below

No default constructor found; nested exception is java.lang.NoSuchMethodException bean configuration

Also I tried to add the lombok.config file in root and copied the Qualifier annotation, that's also not helped.

spring version is 3.2.15. lombok version 1.18.16

It's working fine with below

@Autowired
public TestController(@Qualifier("userDAO") final Test testDAO) {
    this.testDAO = testDAO;
}

How to resolve this?


Solution

  • Adding only an @AllArgsConstructor isn't enough, as it will add the constructor but it doesn't add @Autowired. Because that is missing Spring will look for the default constructor.

    To fix you can do 1 of 3 things

    1. Upgrade to Spring 4.3 or higher, as that will automatically use the single constructor and autowire it
    2. Instruct lombok to add @Autowired to the constructor.
    3. Ditch lombok and just provide the constructor yourself.

    The first should be pretty easy (include a newer version of Spring in your dependencies). The second requires some additional code.

    @Controller
    @RequestMapping(value = "/test")
    @AllArgsConstructor(onConstructor = @__(@Autowired))
    public class TestController {
    
        private final Test testDAO;
    
    } 
    

    The @Qualifier won't work (and should be removed) as it should be on the constructor argument.

    I would just ditch Lombok for this case and just add the constructor (option 3).

    @Controller
    @RequestMapping(value = "/test")
    public class TestController {
    
        private final Test testDAO;
    
        @Autowired
        public TestController(@Qualifier("userDAO") Test testDao) {
            this.testDao=testDao;
        }
    }