gpt4 book ai didi

spring - 通过 BeanPropertySqlParameterSource 存储枚举属性失败并出现 SQLException : Invalid conversion requested

转载 作者:行者123 更新时间:2023-12-02 04:46:53 25 4
gpt4 key购买 nike

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 接口(interface),所以 isStringValue() StatementCreatorUtils 类中的方法“认为”它是一个字符串并调用:

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驱动抛出的,所以也有类似的问题(无法从enum转换成String)。过程参数定义为“IN CHAR”。

抛出的异常是:

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)

编辑:

我找到了 another workaround在 Spring 论坛中:

paramSource.registerSqlType("en", Types.VARCHAR);

最佳答案

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;
}
};

关于spring - 通过 BeanPropertySqlParameterSource 存储枚举属性失败并出现 SQLException : Invalid conversion requested,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32129512/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com