Java,Spring JDBC v3.0.5
我定义了一个DTO,其中包含自定义枚举类型的属性。 当通过 BeanPropertySqlParameterSource 对象将其作为参数发送到存储过程调用时,所有其他属性("普通"类型,如:Long,String和Boolean)工作正常,除了枚举类型。它抛出:
java.sql.SQLException: Invalid conversion requested
查看StatementCreatorUtils.java方法 setValue()我看到它不处理Types.CHAR,它是枚举对象的sqlType(我从调试中知道这一点 - 实际上是SQL过程中声明的参数类型。)
通过 BeanPropertyRowMapper 读取相同的DTO(通过其他程序)可以正常工作。
这是Spring代码中的一些错误或遗漏吗?
DTO看起来像这样:
public class MyDTO extends Serializable {
private Long num;
private Boolean bool;
private String str;
public static enum MyEnum { A , B }
private MyEnum en;
// getters and setters omitted
}
// the call:
new SimpleJdbcCall(m_dataSource).withProcedureName("procedureName").withSchemaName("schema").executeObject(BigDecimal.class, new BeanPropertySqlParameterSource(aMyDTO)).longValue();
我解决了这个问题,让 MyEnum 实现 java.lang.CharSequence 接口,所以 isStringValue()< StatementCreatorUtils 类中的/ em>方法&#34;认为&#34;它是一个字符串并调用:
ps.setString(paramIndex, inValue.toString());
与上面的几行相同:
else if (sqlType == Types.VARCHAR || sqlType == Types.LONGVARCHAR ||
(sqlType == Types.CLOB && isStringValue(inValue.getClass()))) {
ps.setString(paramIndex, inValue.toString());
}
被跳过,因为它不允许使用CHAR sqlType。
使用的数据库是Oracle,并且从Oracle驱动程序抛出实际异常,因此它有类似的问题(无法从枚举转换为String)。 过程参数定义为&#34; IN CHAR&#34;。
抛出的异常是:
Caused by: java.sql.SQLException: Invalid conversion requested
at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:13780)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:13682)
at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:14515)
at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:10918)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:735)
at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:356)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:216)
at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:127)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:212)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:947)
编辑:
我在Spring论坛中找到了another workaround:
paramSource.registerSqlType("en", Types.VARCHAR);
答案 0 :(得分:0)
BeanPropertySqlParameterSource parameterSource = new BeanPropertySqlParameterSource(pojo) {
@Override
public Object getValue(String paramName) throws IllegalArgumentException {
Object value = super.getValue(paramName);
if (value instanceof Enum) {
return value.toString();
}
return value;
}
};