Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法将连接转换为oracle.jdbc.OracleConnection_Java_Oracle_Hibernate_Jdbc_Jndi - Fatal编程技术网

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

Java 无法将连接转换为oracle.jdbc.OracleConnection,java,oracle,hibernate,jdbc,jndi,Java,Oracle,Hibernate,Jdbc,Jndi,为什么java.sql.Connection不能在下面的代码中转换为oracle.jdbc.OracleConnection 我的主要目标是将新用户名传递给Oracle connection,并将其保存在例如“osuser”列中的“SESSION”表中,因为我希望跟踪数据库中的用户更改,并将其显示在表中 @Repository public class AuditLogDAOImpl implements AuditLogDAO { @PersistenceContext(unitNa

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

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

@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
在这种情况下,我通常有两个问题:

  • 为什么从连接到OracleConnection的强制转换失败,以及
  • 实现我的意图的最佳方法是什么(我的意思是在Oracle DB中将新用户名设置为v$session.osuser)
我通过jndi使用Oracle 11g、Hibernate(使用实体管理器)和数据源

请帮忙,谢谢

编辑: 经过一些改进后,铸件的问题仍然存在

改进:

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

连接池通常在实际连接实例周围有一个包装器,这就是您的强制转换失败的原因

无论如何,您所做的不会起作用,因为只有在建立连接时才会检查properties实例中的参数。因为您有一个已处于活动状态的连接,所以它不会更改任何内容


您需要使用tou来更改现有连接的连接。

我在使用spring获取连接时遇到了这个问题。通常,每个层都会在基本类上添加一个包装器。我刚刚完成了connection.getClass().getName()查看正在重新调整的连接的运行时类型。它将是一个包装器/代理,您可以通过它轻松找到获取基本OracleConnection类型的方法。

您正在检索的连接可能是一个已包装的连接

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

if (connection.isWrapperFor(OracleConnection.class)){
   OracleConnection oracleConnection= connection.unwrap(OracleConnection.class);  
}else{
   // recover, not an oracle connection
}
自Java 1.6以来,
isWrapperFor
unwrap
方法都可用,并且应该由A/S连接包装器有意义地实现

我也遇到了同样的问题。我们使用spring,它有一个名为 NativeJdbcExtractor。它有许多实现,下面的一个适用于TomCat。Jboss有一个特定的实现,称为JBossNativeJdbcExtractor

<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean>

这只是为那些通过搜索来这里了解如何在OracleConnection中设置指标的人准备的,我在这方面花了很多时间,所以可能会帮助一些人

在您获得“连接”后,这应该会起作用:

DatabaseMetaData dmd = connection.getMetaData();
Connection metaDataConnection = null;

if(dmd != null)
{
    metaDataConnection = dmd.getConnection();
}

if(!(metaDataConnection instanceof OracleConnection))
{
    log.error("Connection is not instance of OracleConnection, returning");
    return; /* Not connection u want */
}

OracleConnection oraConnection = (OracleConnection)metaDataConnection;

String[] metrics = new String[END_TO_END_STATE_INDEX_MAX]; // Do the rest below...
它适用于我的OracleConnection,但在设置指标时,我面临不同的问题:

short zero = 0;
oraConnection.setEndToEndMetrics(metrics, zero);
在通过我的方法代理连接(其中我设置了几次指标)后,我得到:

java.sql.SQLRecoverableException: No more data to read from socket

但我认为它与一些Spring wiring init或连接池有关。

您可以访问包装器中的内部OracleObject,在本例中是包装器 类型为NewProxyConnection:

DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
(我在我的项目中使用过它,它很有效……没有迷雾,只是使用反射)

试着像下面这样铸造

WrappedConnectionJDK6 wc = (WrappedConnectionJDK6) connection;
connection = wc.getUnderlyingConnection();

下面介绍了AQ的TopicConnection.getTopicSession=>JMS-112

//调试:本机数据源:weblogic.jdbc.common.internal.RmiDataSource
con=DataSource.getConnection();
调试(“通用SQL连接:+con.toString());
//调试:通用连接:weblogic.jdbc.wrapper.PoolConnection\u oracle\u jdbc\u driver\u T4C连接
if(con!=null&&con.isWrapperFor(OracleConnection.class)){
WebLogicNativeJdbcExtractor wlne=新建WebLogicNativeJdbcExtractor();//org.springframework拯救!!
java.sql.Connection nativeCon=wlne.getNativeConnection(con);
this.oraConnection=(OracleConnection)nativeCon;
调试(“展开SQL连接:+this.oraConnection.toString());
}
//调试:本机连接:oracle.jdbc.driver.T4CConnectionè

现在我可以在AQ工厂中使用它了,不知道我的情况是否相关,但是对于我的项目,仅仅更改数据库配置设置实际上会导致展开失败

我将Play框架与Scala一起使用;这只在以下情况下对我有效:

db.withConnection { implicit c  =>
  val oracleConnection = c.unwrap(classOf[OracleConnection])
}
(这只是打开OracleConnection的Scala版本)

当我设置logSql=true时,我得到:

com.sun.proxy.$Proxy17无法强制转换为oracle.jdbc.OracleConnection java.lang.ClassCastException:com.sun.proxy.$Proxy17无法强制转换为 oracle.jdbc.OracleConnection

因此,有关“展开”的某些内容实际上可能会导致“展开”失败。不知道为什么

无论是哪种配置,我的连接对象都是:

HikariProxyConnection@1880261898包装 oracle.jdbc.driver。T4CConnection@6b28f065

isWrapperFor(OracleConnection)
在这两种情况下都是正确的

这种情况发生在Hikari连接池和Bone CP中。也许这是Oracle JDBC中的一个bug

符合MANIFEST.MF的Oracle JDBC驱动程序版本

实施版本:11.2.0.3.0
存储库Id:JAVAVM_11.2.0.4.0_LINUX.X64_130711

经过反复试验。 这种方式有效:

        DelegatingConnection delConnection = new DelegatingConnection(dbcpConnection);
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
但这种方式为oraConnection返回了一个空指针:

DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();

如果您从ClassCastException打印出异常消息,它将告诉您连接对象的实际类是什么。这将帮助您(和我们)理解强制转换失败的原因。找到它是什么对象-通常是System.out.println(连接)连接中的对象是org.jboss.resource.adapter.jdbc.jdk6.wrappedconnectionjdk6如果我理解正确,我可以通过两种方式实现我的目标:1)编辑现有连接(通过
DBMS\u应用程序\u信息。设置\u客户端\u信息()
或2)在连接建立过程中添加用户名,对吗?关于在hibernate中实现这种方法的第二种方法,因为我没有手动创建连接(我已经配置了EntityManagerFactory,并注入了hibernate bean)?@Roman:对不起,我不知道如何配置hibernate。但是,如果使用例如Tomcat的连接池,则可以指定附加属性。手册中记录了具体需要如何完成
DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
    oraConnection = (oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();