在 OpenLiberty 中使用 Oracle XSU 插入数据时出现 ClassCastException

问题描述 投票:0回答:2

我们正在将遗留应用程序从 IBM WebSphere 迁移到 OpenLiberty。某些功能使用 Oracle XSU 来执行数据库操作。

我通过对 java.sql.Connection 执行展开操作,成功获得了 Oracle 特定的连接。

尝试通过 XSU 插入数据时出现错误:

oracle.xml.sql.OracleXMLSQLException:com.ibm.ws.rsadapter.jdbc.v42.WSJdbc42PreparedStatement 无法转换为 oracle.jdbc.OraclePreparedStatement

我的服务器.xml:

获取并解开连接:

尝试使用 XSU 插入:

有人知道如何解决吗?

java oracle open-liberty
2个回答
2
投票

假设 ClassCastException 来自

oracle.xml.sql.dml.OracleXMLSave
(堆栈将确认这一点),您应该针对 Oracle 尝试直接转换为
oracle.jdbc.OraclePreparedStatement
而不是使用
unwrap
从它准备的语句中获取它。提供的连接。看起来您在代码中使用
unwrap
的做法是正确的,但 Oracle 代码需要在准备好的语句的代码中执行同样的操作。


0
投票

假设问题是 Oracle 的 XSU 库没有解包PreparedStatements(感谢@njr),我找到了一个可行的解决方案。

通过 oracleConnection 构建代理,并将其传递给 XSU 库而不是实际的 oracleConnection:

OracleConnection oracleConnection = connection.unwrap(OracleConnection.class); 

OracleConnection proxy = (OracleConnection) Proxy.newProxyInstance(
                        OracleConnection.class.getClassLoader(),
                        new Class<?>[]{OracleConnection.class},
                        new OracleConnectionInvocationHandler(oracleConnection));

OracleXMLSave sav = null;

        try {
            sav = getNewOracleXMLSave(proxy, tableName);
            sav.setRowTag(rowDelimiter);
            sav.setDateFormat("dd/MM/yyyy HH:mm:ss");

            sav.insertXML(xsuXml);

这样,我可以拦截 XSU 库对prepareStatement 方法的调用,并在将对象返回到库之前进行解包。这是代理处理程序:

public class OracleConnectionInvocationHandler implements InvocationHandler {
    private final OracleConnection target;
    private SPELogger systemLog = null;

    public OracleConnectionInvocationHandler(OracleConnection target) {
        systemLog = AppLogger.getInstance();
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if ("prepareStatement".equals(method.getName())) {

            PreparedStatement preparedStatement = (PreparedStatement) method.invoke(target, args);

            systemLog.logInfo(this, "Making PreparedStatement unwrap through OracleConnectionInvocationHandler");

            return preparedStatement.unwrap(oracle.jdbc.OraclePreparedStatement.class);

        }

        return method.invoke(target, args);
    }
}

与此同时,我仍在与 Oracle 联系,看看是否有 XSU 库可以正确处理此问题。但使用代理的解决方案效果很好。

© www.soinside.com 2019 - 2024. All rights reserved.