Spring JavaConfig JdbcDaoSupport

Spring JavaConfig JdbcDaoSupport

This article demonstrate how to use JdbcDaoSupport in Spring JavaConfig.

From Xml Config: Embedded Database

<jdbc:embedded-database id="dataSource" type="H2">
     <jdbc:script location="classpath:schema.sql"/>
     <jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

To JavaConfig: Embedded Database

@Configuration
@ComponentScan(basePackages="com.codeomitted.something")
public class AppContext {
	
  @Bean
  public DataSource dataSource() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    EmbeddedDatabase database = builder.setType(EmbeddedDatabaseType.H2)
	.addScript("classpath:transaction/schema.sql")
	.addScript("classpath:transaction/test-data.sql").build();
	return database;
  }

}

From: MyServiceImpl.java

@Service
public class MyServiceImpl extends JdbcDaoSupport implements MyService {
	
  public void viewStock() {
    String sql = "select * from stock";
    List<Stock> list = getJdbcTemplate().query(sql, BeanPropertyRowMapper.newInstance(Stock.class));
		
    for (Stock stock: list) {
	System.out.println(stock);
    }

}

Change To: 

@Service
public class MyServiceImpl extends JdbcDaoSupport implements MyService {
	
  @Autowired 
  private DataSource dataSource;

  @PostConstruct
  private void initialize() {
    setDataSource(dataSource);
  }

  public void viewStock() {
    String sql = "select * from stock";
    List<Stock> list = getJdbcTemplate().query(sql, BeanPropertyRowMapper.newInstance(Stock.class));
		
    for (Stock stock: list) {
	System.out.println(stock);
    }

}

The reason being use @PostConstruct because the JdbcDaoSupport abstract class had defined a final void setDataSource() method. This is not possible to override setDataSource() method for setter dependency injection. If you try field injection, the exception will be throws as:

Caused by: java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required

Therefore, when bean lifecycle in initialization phase had pass through the Bean Creation and Dependency Injection process, then used BeanPostProcessor bean lifecycle callback to call the setDataSource manually.

Run the client code:

public class Main {

   public static void main(String[] args) {
		
      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
      ctx.register(AppContext.class);
      ctx.refresh();
		
      MyService service = ctx.getBean(MyServiceImpl.class);
      service.viewStock();
		
      ctx.close();
   }
}

 

 

One comment

  1. Wow. Thank you. Lifesaver!!!!

    Reply

Write a Reply or Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.