无法将连接强制转换为 oracle.jdbc.OracleConnection

2022-09-02 23:18:37

为什么java.sql.Connection不能在下面的代码中强制转换为oracle.jdbc.OracleConnection?

我的主要目标是将新用户名传递给Oracle连接,并将其保存在“会话”表中,例如“osuser”列,因为我想在数据库中跟踪用户更改并将其显示在表中。

@Repository
public class AuditLogDAOImpl implements AuditLogDAO {

    @PersistenceContext(unitName="myUnitName")
    EntityManager em;

    @Resource(name = "dataSource")
    DataSource dataSource;

    public void init() {

        try {
            Connection connection = DataSourceUtils.getConnection(dataSource);
            OracleConnection oracleConnection = (OracleConnection) connection; //Here I got cast exception!

            String metrics[] = new String[OracleConnection.END_TO_END_STATE_INDEX_MAX];
            metrics[OracleConnection.END_TO_END_CLIENTID_INDEX] = "my_new_username";

            oracleConnection.setEndToEndMetrics(metrics, (short) 0);

            java.util.Properties props = new java.util.Properties();
            props.put("osuser", "newValue");

            oracleConnection.setClientInfo(props);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

下面是错误日志:

10:42:29,251 INFO  [STDOUT] org.jboss.resource.adapter.jdbc.jdk6.WrappedConnectionJDK6@bcc8cb
10:42:51,701 ERROR [STDERR] java.lang.ClassCastException: $Proxy286 cannot be cast to oracle.jdbc.OracleConnection

通常在这种情况下我有2个问题:

  • 为什么从连接到OracleConnection的强制转换失败以及
  • 实现我的意图的最佳方法是什么(我的意思是在Oracle DB中将新用户名设置为v$session.osuser?

我使用Oracle 11g,Hibernate(使用实体管理器),通过jndi数据源。

请帮忙,谢谢!

编辑:

经过一些改进后,铸造问题仍然存在。

起色:

Connection connection = DataSourceUtils.getConnection(dataSource);
connection = ((org.jboss.resource.adapter.jdbc.WrappedConnection)connection).getUnderlyingConnection();
OracleConnection oracleConnection = (OracleConnection) connection;

错误:

java.lang.ClassCastException: $Proxy287 cannot be cast to org.jboss.resource.adapter.jdbc.WrappedConnection

答案 1

您正在检索的连接可能是包装的连接。

如果您确实需要获取底层 Oracle 连接,则应使用:

if (connection.isWrapperFor(OracleConnection.class)){
   OracleConnection oracleConnection= connection.unwrap(OracleConnection.class);  
}else{
   // recover, not an oracle connection
}

和 方法自 Java 1.6 起可用,并且应由 A/S 连接包装器有意义地实现。isWrapperForunwrap


答案 2

连接池通常有一个围绕真实连接实例的包装器,这就是强制转换失败的原因。

您正在执行的操作无论如何都不起作用,因为只有在建立连接时才会检查属性实例中的参数。由于您的连接已处于活动状态,因此它不会更改任何内容。

您需要使用DBMS_APPLICATION_INFO。SET_CLIENT_INFO() 以更改现有连接的此设置。


推荐