2011-04-27 63 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