Reputation: 2894
I am learning Spring. I came around using Spring with JDBC and also read about Autowiring.
So I wrote this
public class JdbcAccess {
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
System.out.println("setDataSource called");
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public void getCount1() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(getDataSource());
int count = jdbcTemplate.queryForInt(sql);
System.out.println("Result is = " + count);
}
public void getCount2() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
int count = jdbcTemplate.queryForInt(sql); // Line 66
System.out.println("Count = " + count);
}
}
I expect below as output:
setDataSource called
Count = 3
What I get:
Exception in thread "main" java.lang.NullPointerException at playwithspring.JdbcAccess.getCount2(JdbcAccess.java:66)
This means setDataSource(..)
, isn't being called by Spring, but Spring framework is setting the data source correctly, because getCount1()
, which makes a call to getDataSource()
runs fine. So my questions are:
Please note: I run either getCount1()
or getCount2()
Upvotes: 2
Views: 1320
Reputation: 9100
Instead of
Field Injection
@Autowired
private DataSource dataSource;
USE Setter Injection instead of Field injection if you want setter to be called.
@Autowired
public void setDataSource(DataSource dataSource) {
System.out.println("setDataSource called");
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
Upvotes: 4
Reputation: 401
The reason for the exception is because your setDataSource
is not called as Spring uses reflection for setting the data source.
You have two good options to set it, either annotate your setter method with @Autowired or you could leave your current annotation on the dataSource variable and use @PostConstruct annotation to initialize your jdbcTemplate
which I think would lead to a cleaner code.
@Autowired
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
@PostConstruct
private void init() {
jdbcTemplate = new JdbcTemplate(dataSource);
System.out.println("jdbTemplate created");
}
public void getCount2() {
String sql= "SELECT COUNT(*) FROM MYTABLE";
int count = jdbcTemplate.queryForInt(sql);
System.out.println("Count = " + count);
}
Upvotes: 3