To populate a temporary database table, most of us would write something like this:

-- Assume table TempData exists
Truncate table TempData;
Insert Into TempData
Select ... From ... Where id = 1234 and Flag Is Not NULL;

Trevor A.'s cohort decided to use Spring to help do it better:


    <bean id="ourReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step">
       <property name="saveState" value="false" />
       <property name="dataSource" ref="ourDataSource" />
       <property name="rowMapper" ref="filterRowMapper" />
       <property name="fetchSize" value="5000" />
       <property name="prepatedStatementSetter">
           <bean class="org.springframework,batch.core.resource.listPreparedStatementSetter">
              <property name='parameters">

    <bean id="ourValidator" class="org.springframework.batch.core.job.DefaultJobParametersValidator" >
       <property name="requiredKeys">
           <array value-type="">

    <bean id="filterRowMapper" class="x.y.z.FilterRowMapper" />

    <bean id="theDao" class="x.y.z.TheDao">
       <constructor-arg ref="ourDataSource" />
       <constructor-arg value="Truncate Table TempData" />

    <bean id="truncateTemptTable" class="x.y.z.TruncateTempTable">
       <constructor-arg ref="theDao"/>

    <bean id="ourProcessor" class="x.y.z.OurProcessor"/>

    <bean id="ourWriter" class="x.y.z.OurWriter" scope="step">
       <constructor-arg ref="theJdbcTemplate"/>
       <constructor-arg value="insert into tempdata values(?,?, ..., ?)"/>

    <batch:job id="loadTempTable">
       <batch-description>Load the temp table for id: 1234</batch:description>
       <batch:validate ref="ourValidator"/>
       <batch:step id="step1" next="step2">
           <batch:tasklet ref="truncateTempTable"/>
       <batch:step id="step2">
               <batch:chunk reader="ourReader" processor="ourProcessor" writer="ourWriter" commit-interval="5000"/>

public class FilterRowMapper implements RowMapper<MyRecord> {
  public final static String COL_1 = "ColName-1";
  // ...
  public final static String COL_N = "ColName-n";

  public MyRecord mapRow(ResultSet rs, int rowNum) throws SQLException {
    MyRecord r = new MyRecord();
    // ...
    return r;

public class TruncateTempTable implements Tasklet {
  private TheDao dao;

  public TruncateTempTable(TheDao dao) {
    this.dao = dao;

  public RepeatStatus execute(StepContribution sc, ChunkContext cc) throws Exception {
    return RepeatStatus.FINISHED;

public class TheDao extends NamedParametersJdbcDaoSupport {
  private String truncateTempTableSql;

  public TheDao(DataSource ds, String sql) {
    truncateTempTableSql = sql;

  public void truncateTempTable() {

public class OurProcessor implements ItemProcessor<MyRecord, MyRecord> {

  public MyRecord process(MyRecord in) throws Exception {
    MyRecord out = in;
    return out;

public class OurWriter implements ItemWriter<MyRecord> {
  private JdbcTemplate jt;
  private String sql;

  public OurWriter(JdbcTempalte jt; String sql) {
    this.jt  = jt;
    this.sql = sql;

  public void write(List<? extends MyRecord> list) throws Exception {
    for (MyRecord r : list) {
        if (r.getFlag() != null) {
           jt.batchUpdate(sql, new BatchPreparedStatementSetter() {

             public void setValues(PreparedStatement ps, int rowNum) throws Exception {
               // ...

             public int getBatchSize() {
               return list.size();

Don't get me wrong, I'm all for utilizing tools to help get things done, but when the tool obfuscates what you're trying to accomplish, perhaps it's not helping as much as you think it's helping.

Axiom: 95% of the cost of software is in maintenance and upgrades: if the next person can't figure out what you did without your help, you didn't do as good a job as you might think!