I am having issues understanding how the dataSource
autowiring works in Spring. From what I read on the internet Spring should automatically set its dataSource
bean from the application.properties
. So initially what I did is that I filled my application.properties
as follows
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xmlconverter
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
So far so good. Then I continued reading https://www.javatpoint.com/spring-boot-jdbc and as many other sources suggest dataSource
should be configured now. Now if I want to write a query I just have to create a class annotate it with @Service
or @Component
then
@Autowire
private jdbcTemplate template;
and then I could use the template
to issue my queries. Okay, I did that. I wrote the simplest class that queries a MySQL database for the current system date and time.
@Service
public class SystemDate {
@Autowired
private JdbcTemplate template;
public String getSystemDate() {
String sql = "SELECT SYSDATE();";
return new String (template.queryForObject(sql, String.class));
}
}
Having done that I wanted to test if it works. So I went in the main class of my project and I did the following.
@SpringBootApplication
public class Application {
@Autowired
private static SystemDate date;
public static void main(String[] args){
SpringApplication.run(Application.class, args);
System.out.println(date.getSystemDate());
}
}
When I run the application I got a null pointer exception.
Exception in thread "main" java.lang.NullPointerException
at com.Application.main(Application.java:24) // that's the System.out.print line
Having this error I read the following questions.
However, what bothered me was that those questions are 4+ years old, but I decided to give them a go. So next what I tried was to create dataSource
bean and jdbcTemplate
bean. As the answers in the second post suggests I produced the following class.
@Configuration
public class JdbcTemplateConfiguration{
@Bean (name = "dataSource")
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/xmlconverter");
dataSource.setUsername( "root" );
dataSource.setPassword("");
return dataSource;
}
@Bean (name = "jdbcTemplate")
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
Okay...now I have initialised the 2 beans so I can finally print the system date and time, therefore I did not change any of the previously mentioned classes. It should work now, right? I have a bean that provides configuration for jdbcTemplate
and I have @Autowire
-d jdbcTemplate
in my SystemDate.class
. When I ran it...again Null ponter exception....
Then I researched a bit deeper and I found that - https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-configure-a-datasource
So next I tried to modify my dataSource
bean as it was shown in the spring docs. This resulted in
@Configuration
@EnableConfigurationProperties
public class JdbcTemplateConfiguration{
@Bean
@ConfigurationProperties("spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
//jdbc template remains the same
}
The result was still a null pointer exception. So the final thing I attempted was to completely remove the SystemDate.class
and include the getSystemDate()
in JdbcTemplateConfiguration.class
, but then I got this....
Exception in thread "main" java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
This bugs me to the core because I feel I am missing something small, but I am not sure what. Let me explain what I want to achieve. I want to create Spring Project that takes its database configuration from application.properties
and using jdbcTemplate
queries a database to get its system date and time. Some questions I have are...
Questions
- Is it possible to configure spring to take its database properties from
application.properties
. If yes, what am I doing wrong? - Is it necessary to define
@Beans
fordataSource
andjdbcTemplate
? - How can I make the
jdbcTemplate
configuration generic. By generic I mean that I want the connection properties to be specified only in application.properties and no where else.
P.S Last time I posted a similar question and it got marked as duplicate. I think I am much more descriptive this time and as I already mentioned some of the replies on similar questions are 4+ years old, so I don't think they are still relevant. I hope it won't be marked this time