Processing Stored Procedure result sets in Spring

March 8th, 2008 by stevi | Filed under Java

Recently, I was using Spring‘s JDBCTemplate for my Data Access Layer (DAL). I had a stored procedure that returned a result set, and had to spend quite a bit of search time finding an example of how to process it.

I managed to work it out using both the method of overriding Spring’s StoredProcedure and using the simple JDBCTemplate.query(sql, args, rowMapper). I found the latter to be simpler, since it doesn’t involve a inner class, etc., so here’s a complete example for anyone else who might need to try. Note the assumption that this is a Spring-managed application, so the dataSource is being injected.

This works as early as Spring 1.2.9 and Java 1.3.

package com.stevideter.business.dal.spring;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
 
import javax.sql.DataSource;
 
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
 
import com.stevideter.business.Customer;
import com.stevideter.business.ApplicationException;
 
/**
 * CustomerSpringDao ...
 * @author stevi.deter@gmail.com
 * @version     %I%, %G%
 * @since       1.0
 **/
 
public class CustomerSpringDao {
 
    private JdbcTemplate jdbcTemplate;
 
    public Customer get(Long accountNumber) throws ApplicationException {
        if (accountNumber == null) {
            throw new IllegalArgumentException();
        }
        if (getJdbcTemplate() == null) {
            throw new ApplicationException(ApplicationException.NULL_DAO);
        }
        try {
            List customers = getJdbcTemplate().query(
                    "call PACKAGE.GET_CUSTOMER(?)",
                    new Object[] { accountNumber }, new CustomerMapper());
            if (CollectionUtils.isNotEmpty(customers)) {
                // return the first one
                return (Customer)customers.get(0);
            }
            return null;
        } catch (DataAccessException ex) {
            throw new ApplicationException(ApplicationException.DATA_ACCESS_ERROR);
        }
    }
 
    /**
    * CustomerMapper processes a ResultSet to populate a Customer object
    * @author stevi.deter@gmail.com
    * @version     %I%, %G%
    * @since       1.0
    *
     */
    protected static final class CustomerMapper implements RowMapper {
 
        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Customer customer = new Customer();
            customer.setAccountNumber(new Long(rs.getLong("ACCOUNTNUMBER")));
            customer.setLastName(StringUtils.trimToNull(rs.getString("LASTNAME")));
            customer.setFirstName(StringUtils.trimToNull(rs.getString("FIRSTNAME")));
            return customer;
        }
    }
    /**
     * Spring DI for the datasource. instantiates the JdbcTemplate
     * @param dataSource
     */
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    /**
     * @return the jdbcTemplate
     */
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
}

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

tag_iconTags: | | | |

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

9 Responses to “Processing Stored Procedure result sets in Spring”.

  1. [...] my previous post, I gave an example of code on how to use Spring’s JDBCTemplate to call a stored procedure and [...]

  2. nodoubt :

    Can you please provide Oracle PLSQL code snippet? thanks

  3. Charlie :

    I am trying to implement the above using the following stored procedure and am having problems:
    PROCEDURE get_next_event (
    p_uuid IN VARCHAR2,
    curvar_out OUT tcdn_eventdata_defs.curvar_type

    )

    Can it be done using jdbcTemplate

  4. I think you’ll want to use the method of overriding the StoredProcedure as I show in this post.

    I think you’ll probably want to modify this line:
    declareParameter(new SqlReturnResultSet(“rs”, new CustomerMapper()));

    to be something like:
    declareParameter(new SqlReturnResultSet(“curvar_out”, new CustomerMapper()));

  5. Krishna :

    Does the above example work?Because I am getting an error saying “stored procedure nor function not found”

  6. Krishna,
    Have you created a stored procedure “GET_CUSTOMER” in package “PACKAGE” that takes one parameter or replaced the name in the sample with the stored procedure you want to use?

  7. Martin :

    Hi.
    I have followed your instructions – thank you very much; I get
    PLS-00306: wrong number or types of arguments in call to ‘SL_TEST’
    bad SQL grammar [{? = call SL_TEST(?, ?, ?, ?, ?, ?, ?, ?, ?)}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 13:

    …now, there are nine “?” there in those brackets; I in fact declare ten parameters, one of which is the row mapper result set one.

    I am wondering if the definition of the result set parameter is incorrect, in our oracle PL/SQL. Would it be possible to provide the PL/SQL used to generate your SP?

    I have loads of other working stored procedure calls to our Oracle10G db.

    Thanks very much!

    Martin

  8. Martin :
  9. [...] Processing Stored Procedure result sets in Spring | Moving the Curve (tags: java springframework) [...]

Leave a comment.

To leave a comment, please fill in the fields below.