-1

I'm trying to autowire jdbctemplate in MessageBoxDAO class (which i guess is working fine), then i create autowired DAO object in the controller to get the latest ID in order to counter not getting repetitive IDs and start where it ended.

Here's the code:

@Component
public class MessageBoxDAO {

    @Autowired
    JdbcTemplate jdbcTemplate;

...

    public long getLatestID() {
        return jdbcTemplate.queryForObject("SELECT id FROM messages ORDER BY id DESC LIMIT 1", Integer.class);
    }
}
@RestController
public class MessageBoxController {

    @Autowired
    MessageBoxDAO dao;

    private final AtomicLong counter = new AtomicLong(dao.getLatestID());

...
}

For some unknown to me reason "dao" is null, hence counter cannot be constructed and the program stops

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.CRUD.MessageBoxController]: Constructor threw exception; nested exception is java.lang.NullPointerException: Cannot invoke "com.example.CRUD.MessageBoxDAO.getLatestID()" because "this.dao" is null

I'm new to spring boot and I understand it might be a very simple problem, but can somebody point out where am I being wrong?

karczi
  • 21
  • 1
  • 3
  • 3
    Field injection happens after the object is constructed. Field initialisation happens during construction. Use constructor injection and initialise `counter` in your constructor. – tgdavies Jul 15 '22 at 12:14

2 Answers2

4

The issue you're facing is due to initialization of the following object

private final AtomicLong counter = new AtomicLong(dao.getLatestID());

You've Autowired the MessageBoxDAO dependency which is not initialized at the time of execution of the above instruction. Either you should initialize the counter after the completion of instantization process or use construction injection.

b.s
  • 2,409
  • 2
  • 16
  • 26
3

counter is a member variable of MessageBoxController. Spring use reflection to construct MessageBoxController instance. It would be initialized before dependency injection of dao. More details can be found here: https://stackoverflow.com/a/49443630/6644123
We can try to rewrite counter's initialization time. An example may be like code below:

@RestController
public class MessageBoxController {
    @Autowired
    MessageBoxDAO dao;

    private final AtomicLong counter = new AtomicLong(0);

    @PostConstruct
    public void initialize() {
        // initialize counter after dependency injection of dao
        counter.set(dao.getLatestID());
    }
...
}
shanfeng
  • 503
  • 2
  • 14