早上好!
我正在尝试从 Websphere 6.5 升级到 8.5。当应用程序将xml数据提交到数据库时,我收到以下错误:
Caused by:
java.sql.SQLException: java.lang.IllegalAccessException: Class com.ibm.ws.rsadapter.jdbc.WSJdbcUtil can not access a member of class oracle.jdbc.driver.OraclePreparedStatementWrapper with modifiers "public"
at com.ibm.ws.rsadapter.AdapterUtil.toSQLException(AdapterUtil.java:1727)
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:684)
at com.ibm.ws.rsadapter.jdbc.WSJdbcUtil.call(WSJdbcUtil.java:377)
at com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(WSCallHelper.java:302)
at J.D.A.A.WASOracleXMLType.nullSafeSet(Unknown Source)
at J.D.A.A.A.nullSafeSet(Unknown Source)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:146)
经过一段时间的调查,我认为我已经找到了给我带来问题的原因:一个名为 jdbcCall 的 WebSphere 方法在 WebSphere 6.5 中有 5 个参数,但现在可以有 6 个参数。
该方法描述如下:https://www-01.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/rsadapter/WSCallHelper.html参数是这样的:
**vendorClassName** - The name of the vendor-specific interface class
on which methName is defined. This value can be used in cases where the
implementation class of the vendor's JDBC object is a protected class, i.e.
calling methName on the underlying JDBC object produces an **IllegalAccessException**. This value should specify the name of the vendor's recommended Class/Interface which is extended/implemented by the underlying JDBC object. For example "oracle.jdbc.driver.OracleResultSet" may need to be specified when the underlying object is an OracleResultSetImpl object. If not needed, this value may be null.
这是我的实现:
com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(
null,
a-Prepared-Statement, //OraclePreparedStatementWrapper
"setObject",
new Object[]{new Integer(index), xmlType},
new Class[]{int.class, Object.class})
所以,我已经阅读了文档,但我不明白我应该插入什么作为vendorClassName,也许"oracle.jdbc.OracleDriver"就足够了?谁能更好地解释我能理解我应该在这个参数中插入什么?
否则,您认为问题是什么?
我正在使用 Oracle12c、ojdbc6 和 WebSphere 8.5
谢谢!
为什么你需要使用WSCallHelper.jdbcCall()
?
由于PreparedStatement.setObject(int, Object)
完全是 JDBC 标准,因此您可以在语句对象上调用它,而无需执行任何类型的解包。 仅当需要调用特定于供应商的 API 时,才应尝试解包 WebSphere JDBC 连接。
只需做:
aStatement.setObject(index, xmlType);
如果您需要访问供应商特定的 API:WSCallHelper.jdbcCall()
的使用已经过时了。 我建议改用Connection.unwrap(Class<?>)
。
例:
OraclePreparedStatement oracleStmt = aStatement.unwrap(OraclePreparedStatement.class);
如果你真的,真的需要使用WSCallHelper.jdbcCall()
:
传入供应商类名将允许 WebSphere 装入供应商类,并在应用正确的类装入器的情况下以特权方式执行调用操作。
是您尝试调用的供应商对象的类名。 因此,如果您将语句与 oracle 驱动器一起使用,则可以传入字符串"oracle.jdbc.OracleStatement"作为您的 vendorClassName。
例:
com.ibm.websphere.rsadapter.WSCallHelper.jdbcCall(
null,
aStatement, // WSJdbcPreparedStatement wrapping an OraclePreparedStatement
"someOracleSpecificMethod",
new Object[]{new Integer(index), xmlType},
new Class[]{int.class, Object.class},
"oracle.jdbc.OracleStatement");