Results 1 to 4 of 4

Thread: Is RowMapperResultReader caching result list?

  1. #1
    Join Date
    Oct 2005
    Posts
    2

    Default Is RowMapperResultReader caching result list?

    Hi,

    I've just come accross what seems to me, to be rather odd behaviour when using a RowMapperResultReader.

    Basically, I'm accessing an oracle stored procedure that returns a cursor as one of it's out parameters. My code is as follows:

    HTML Code:
    public class PositionHistoryFindByPK extends StoredProcedure {
    
        private static final String SQL = "lv_sys.tracklog_interface_pkg.find_by_primary_key";
    
        private RowMapperResultReader resultReader = null;
    
        protected PositionHistoryFindByPK(DataSource dataSource) {
            RowMapper rowMapper = new PositionHistoryRowMapper();
            this.resultReader = new RowMapperResultReader(rowMapper, 1);
            setDataSource(dataSource);
            setSql(SQL);
            declareParameter(new SqlParameter("i_pk", Types.INTEGER));
            declareParameter(new SqlOutParameter("o_result", OracleTypes.CURSOR, this.resultReader));
        }
    
        public PositionHistoryVO getValueObject(Integer pk) {
                Map params = new HashMap(1);
                params.put("i_pk", pk);
                execute(params);
                return (PositionHistoryVO) DataAccessUtils.uniqueResult(this.resultReader.getResults());            
        }
    
    }
    All works fine the first time round. When, however, I try to get another result (with the same parameters), with the same PositionHistoryFindByPk object, it fails at the uniqueResult function, throwing a IncorrectResultSizeDataAccessException. It appears that the result size is equal to the number of calls I have made to getValueObject(pk)

    If, however, I change the getValueObject code to read
    HTML Code:
            synchronized (this.resultReader){
                this.resultReader.getResults().clear();
                Map params = new HashMap(1);
                params.put("i_pk", pk);
                execute(params);
                return (PositionHistoryVO) DataAccessUtils.uniqueResult(this.resultReader.getResults());
            }
    then everything works fine - the clearing of the results list between calls cures the problem.

    Questions:

    1) Is this the desired behaviour of the RowMapperResultReader?
    2) If so, please explain why
    3) Am I abusing the RowMapperResultReader? If so, how should it be used?

    TIA


    John Grange

  2. #2
    Join Date
    Aug 2004
    Posts
    1,104

    Default

    The JavaDoc states:
    Note that a RowMapper object is typically stateless and thus reusable;
    * just the RowMapperResultReader adapter is stateful.

    I think you would be better off using a plain RowMapper and coding your parameter similar to this:

    Code:
    declareParameter(new SqlReturnResultSet("o_result", new RowMapper() {
    	public Object mapRow(ResultSet rs, int rowNum)
    		throws SQLException {
    		Xxxx x = new Xxxx();
    		//x.set .... set your properties here
    		return x;
    	}
    }));
    Then you can retrieve the List of returned objects from the Map returned in the execute call.
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

  3. #3
    Join Date
    Oct 2005
    Posts
    2

    Default

    Forgive me for being dense, please, but where do i get the list of objects mapped by the rowmapper back?

    also, is there some magic I must perform to get this to work with oracle?

    TIA

  4. #4
    Join Date
    Aug 2004
    Posts
    1,104

    Default

    Sorry, I forgot to include the SQLType - this should work for Oracle:

    Code:
    declareParameter(new SqlReturnResultSet("o_result", OracleTypes.CURSOR, new RowMapper() {
            public Object mapRow(ResultSet rs, int rowNum)
                    throws SQLException {
                    Xxxx x = new Xxxx();
                    //x.set .... set your properties here
                    return x;
            }
    }));
    Now, to get the List of returned objects you retrieve then from the output Map using the parameter name you used when you declared parameter. So in this case it would be:
    Code:
    List l = (List) outputMap.get("o_result");
    Thomas Risberg
    SpringSource by Pivotal
    http://www.springsource.org

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •