在使用Spring中的NamedParameterJdbcTemplate.queryForRowSet()方法時(shí),拋出了SQLException:Invalid scale size. Cannot be less than zero的異常。
google之后知道出現(xiàn)這種錯(cuò)誤有兩種情況:
1是當(dāng)所查詢的列類型為number,而且沒有指定具體的精度時(shí)。處理這個(gè)問題相對來說比較簡單,更改列類型增加精度就可以了;
2是當(dāng)數(shù)據(jù)庫環(huán)境為oracle而且使用了RowSet時(shí)。具體原因是由于“oracle驅(qū)動面對一個(gè)數(shù)值型的返回字段時(shí),在得到指定的字段小數(shù)點(diǎn)右邊的數(shù)值數(shù)量時(shí)(Gets the designated column's number of digits to right of the decimal point.這個(gè)是原文),居然會返回-127,而oracle本身的cacheRowSet實(shí)現(xiàn)不允許這種情況出現(xiàn),于是就會報(bào)標(biāo)題所說的異常。”(原文出自馬面薩滿的靈魂小屋)
針對問題2的解決辦法就要復(fù)雜的多,需要對ResultSetMetaData中g(shù)etScale()方法的原有的返回結(jié)果加以處理,需要修改的部分如下,其它部分照舊重寫即可。
為了在spring中應(yīng)用我們所實(shí)現(xiàn)的ResultSetWrapper和ResultSetMetaDataWrapper,需要重寫spring中的SqlRowSetResultSetExtractor和NamedParameterJdbcTemplate,具體代碼如下
google之后知道出現(xiàn)這種錯(cuò)誤有兩種情況:
1是當(dāng)所查詢的列類型為number,而且沒有指定具體的精度時(shí)。處理這個(gè)問題相對來說比較簡單,更改列類型增加精度就可以了;
2是當(dāng)數(shù)據(jù)庫環(huán)境為oracle而且使用了RowSet時(shí)。具體原因是由于“oracle驅(qū)動面對一個(gè)數(shù)值型的返回字段時(shí),在得到指定的字段小數(shù)點(diǎn)右邊的數(shù)值數(shù)量時(shí)(Gets the designated column's number of digits to right of the decimal point.這個(gè)是原文),居然會返回-127,而oracle本身的cacheRowSet實(shí)現(xiàn)不允許這種情況出現(xiàn),于是就會報(bào)標(biāo)題所說的異常。”(原文出自馬面薩滿的靈魂小屋)
針對問題2的解決辦法就要復(fù)雜的多,需要對ResultSetMetaData中g(shù)etScale()方法的原有的返回結(jié)果加以處理,需要修改的部分如下,其它部分照舊重寫即可。
?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?}
?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中應(yīng)用我們所實(shí)現(xiàn)的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.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));
??}
}
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時(shí)出現(xiàn)的該錯(cuò)誤。或許它更應(yīng)該和RowSet、oracle驅(qū)動的版本有關(guān);)