hpfyeah

首页 新随笔 联系 聚合 管理
  3 Posts :: 1 Stories :: 3 Comments :: 0 Trackbacks
在使用Spring中的NamedParameterJdbcTemplate.queryForRowSet()方法时,抛出了SQLException:Invalid scale size. Cannot be less than zero的异常。

google之后知道出现这种错误有两种情况:

1是当所查询的列类型为number,而且没有指定具体的精度时。处理这个问题相对来说比较简单,更改列类型增加精度就可以了;

2是当数据库环境为oracle而且使用了RowSet时。具体原因是由于“oracle驱动面对一个数值型的返回字段时,在得到指定的字段小数点右边的数值数量时(Gets the designated column's number of digits to right of the decimal point.这个是原文),居然会返回-127,而oracle本身的cacheRowSet实现不允许这种情况出现,于是就会报标题所说的异常。”(原文出自马面萨满的灵魂小屋

针对问题2的解决办法就要复杂的多,需要对ResultSetMetaData中getScale()方法的原有的返回结果加以处理,需要修改的部分如下,其它部分照旧重写即可。
 1 public class ResultSetWrapper implements ResultSet {
 2     public ResultSetWrapper(ResultSet wrapped) {
 3         this.wrapped = wrapped;
 4     }
 5    
 6    public ResultSetMetaData getMetaData() throws SQLException {
 7         // TODO Auto-generated method stub
 8         // return null;
 9         return new ResultSetMetadataWrapper(this.wrapped.getMetaData());
10     }
11}  
12  
13
14 public class ResultSetMetadataWrapper implements ResultSetMetaData {
15    
16     public int getScale(int arg0) throws SQLException {
17         // TODO Auto-generated method stub
18         //return 0;
19         
20         int result = this.wrapped.getScale(arg0);
21         return result < 0? 0: result;
22     }
23 }

为了在spring中应用我们所实现的ResultSetWrapper和ResultSetMetaDataWrapper,需要重写spring中的SqlRowSetResultSetExtractor和NamedParameterJdbcTemplate,具体代码如下
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.rowset.CachedRowSet;

import org.springframework.jdbc.core.SqlRowSetResultSetExtractor;
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSet;

public class CustomSqlRowSetResultSetExtractor
    
extends
      SqlRowSetResultSetExtractor {

  
protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
    CachedRowSet rowSet 
= newCachedRowSet();
    rowSet.populate(
new ResultSetWrapper(rs));
    
return new ResultSetWrappingSqlRowSet(rowSet);
  }

}

import java.util.Map;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.rowset.SqlRowSet;

public class CustomNamedParameterJdbcTemplate extends NamedParameterJdbcTemplate {
  
public CustomNamedParameterJdbcTemplate(DataSource ds) {
    
super(ds);
  }

  
public SqlRowSet queryForRowSet(String sql, SqlParameterSource paramSource) throws DataAccessException {
    
return (RowSet) getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), new CustomSqlRowSetResultSetExtractor());
  }

  
public SqlRowSet queryForRowSet(String sql, Map paramMap) throws DataAccessException {
    
return queryForRowSet(sql, new MapSqlParameterSource(paramMap));
  }
}

在需要使用NamedParameterJdbcTemplate的地方使用我们自定义的CustomNamedParameterJdbcTemplate即可。需要说明的是我是在使用spring版本2.0.*、2.5.5时出现的该错误。或许它更应该和RowSet、oracle驱动的版本有关;)

posted on 2008-07-19 22:22 hpfyeah 阅读(3086) 评论(1)  编辑  收藏 所属分类: j2ee

Feedback

# re: 在Spring中处理SqlRowSet的SQLException:Invalid scale size. Cannot be less than zero异常 2009-01-24 23:36 mam
ah mamah  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: