Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

  1. JdbcTemplate NullPointerException
  2. JDBCTemplate giving Null Pointer Exception?

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

  1. Is it possible to configure spring to take its database properties from application.properties. If yes, what am I doing wrong?
  2. Is it necessary to define @Beans for dataSource and jdbcTemplate ?
  3. 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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.1k views
Welcome To Ask or Share your Answers For Others

1 Answer

等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...