2011-04-27 61 views
2

我处于有史以来最伟大的混合物的竞争者中间。我需要使用Spring JDBC而不用参考它。自定义类加载器提供了上下文,我需要使用反射来调用这些方法。其中一种方法是SimpleJdbcCall.declareParameters(SqlParameter ...)反射超载。为反射可变参数值填充反射数组方法

我的问题是创建并设置可变参数SqlParameter(这些实例也必须反映出来)。我需要将一个参数绑定到数组中以满足可变参数签名。

以下,为了简洁起见省略了类加载。但假设Class<?> simpleJdbcCallClass = SimpleJdbcCall.class

Constructor sqlOutParameterConstructor = 
    sqlOutParameterClass.getConstructor(String.class, int.class); 
Object sqlOutParameter = sqlOutParameterConstructor.newInstance(param, type); 

Object paramArray = Array.newInstance(sqlParameterArrayClass, 1); 
Array.set(paramArray, 0, sqlParameterClass.cast(sqlOutParameter)); 
// IllegalArgumentException thrown above. 
// It is thrown without the call to .cast too. 

Method declareParametersMethod = 
    simpleJdbcCallClass.getMethod("declareParameters", sqlParameterArrayClass); 
declareParametersMethod.invoke(procedure, paramArray); 

引发的异常是:

java.lang.IllegalArgumentException: array element type mismatch 
at java.lang.reflect.Array.set(Native Method) 

该方法以SqlParameter ...和我有一个子类SqlOutParameter的一个实例。因此我尝试用sqlParameterClass.cast(sqlOutParameter)进行投射。抛出或不抛出此异常时抛出异常。

调试我可以证实,paramArraySqlParameter[]sqlParameterClass.cast(sqlOutParameter)SqlOutParamter(不SqlParameter铸)。我怀疑这可能是问题所在。

+0

只是好奇,但我很想知道这个 – 2011-04-27 03:18:20

+0

背后的故事几个月前,我进行了一次重要的重构,将SQLExecutor的使用转换为Spring 3 JDBC(以解决严重的竞争条件)。我们的应用程序驻留在捆绑Spring 1的供应商框架内。Spring JDBC中的一些签名已在这些版本中进行了更改。这导致MethodNotFoundExceptions或类似的在运行时。虽然我们等待供应商升级到Spring 3,但我只为我们的DAO黑客入侵Spring 3 JDBC的动态负载。快乐开心,欢乐喜悦。 – Synesso 2011-04-27 04:27:36

+2

哎唷!我的哀悼 – 2011-04-27 14:27:59

回答

2

我认为这个问题是在这一行:

Object paramArray = Array.newInstance(sqlParameterArrayClass, 1); 

具体来说,你不告诉我们什么sqlParameterArrayClass是,但基于我猜是类数组类型的名称。实际上,它需要是数组元素的类;请参阅用于newInstance(...)方法的javadoc。

+1

另外对'Class.cast()'的调用可能是不必要的,你不觉得吗? – 2011-04-27 02:56:46

+0

是的,这是问题。而演员是不必要的(这是我的故障排除的一部分,如问题中所述)。 – Synesso 2011-04-27 03:01:45