连接不能转换为oracle.jdbc.OracleConnection(Connection can

2019-07-21 21:53发布

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

我的主要目标是通过对Oracle连接新的用户名,并将其保存在例如“OSUSER”列“会话”表,因为我想在DB用户更改跟踪,并在表中显示。

@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数据库中设置新的用户名以V $ session.osuser的最佳方式?

我与Oracle 11g中,休眠(使用实体管理器),通过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

Answer 1:

要检索的连接可能是一个包裹连接。

如果你真的需要得到底层Oracle连接,您应该使用:

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

isWrapperForunwrap的方法是从Java 1.6可用,并且应该由A / S连接包装进行有意义的实现。



Answer 2:

连接池通常有真正的连接实例周围的包装,这就是为什么你的施法失败。

你在做什么不反正工作,因为在属性实例的参数在建立连接时,只检查。 当你有一个已激活的连接,它不会改变任何东西。

你需要使用土特产品DBMS_APPLICATION_INFO.SET_CLIENT_INFO()为了改变这种现有连接。



Answer 3:

这仅仅是通过谁如何在设定的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

但我认为它有一些弹簧接线inits或连接池做。



Answer 4:

用春天的时候让我连接了面临这个问题。 典型地,每个层增加了在基本类的包装。 我刚刚做connection.getClass()的getName()来查看连接的运行时类型进行重新调整。 这将是一个包装/代理了,你可以很容易地找到得到基本的OracleConnection类型的方法。



Answer 5:

您可以访问内部OracleObject一个包装里面,在这种情况下,封装类型为NewProxyConnection:

(我在我的项目中使用它,它的工作...没有谜,只需要使用反射)

Field[] fieldsConn= connection.getClass().getDeclaredFields();

Object innerConnObject = getFieldByName(fieldsConn,"inner").get(connection);


if(innerConnObject instanceof OracleConnection ){
  OracleConnection oracleConn = (OracleConnection)innerConnObject;
 //OracleConnection unwrap = ((OracleConnection)innerConnObject).unwrap();
  // now you have the OracleObject that the Wrapper 
}


//Method: Set properties of the ooject accessible.
 public static  Field getFieldByName(Field[] campos, String name) {
    Field f = null;
    for (Field campo : campos) {
        campo.setAccessible(true);
        if (campo.getName().equals(name)) {
            f = campo;
            break;
        }
    }
    return f;
 }


Answer 6:

请尝试以下

我曾遇到同样的问题。 我们使用的弹簧,它有一个叫NativeJdbcExtractor类。 它有许多的实现和下面一个作品为Tomcat。 有一个具体的实施对于JBoss称为JBossNativeJdbcExtractor

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

在你的DAO,你可以注入豆,用下面的方法

protected NativeJdbcExtractor jdbcExtractor;
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection);


Answer 7:

不知道我的情况是相关的,但我的项目,只需更改数据库配置设置实际上会展开失败!

我使用Scala的播放框架; 这个工作对我来说,只有当logSql = FALSE

db.withConnection { implicit c  =>
  val oracleConnection = c.unwrap(classOf[OracleConnection])
}

(这只是展开一个OracleConnection的斯卡拉版)

当我设置logSql =真 ,我得到:

。com.sun.proxy $ Proxy17不能转换到oracle.jdbc.OracleConnection java.lang.ClassCastException:com.sun.proxy $ Proxy17不能转换为oracle.jdbc.OracleConnection

因此,一些关于logSql配置实际上可以导致展开失败。 不知道为什么。

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

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

isWrapperFor(OracleConnection)是在两种情况下真

这种情况与阿光连接池和骨CP。 也许这是在甲骨文JDBC中的错误?

根据MANIFEST.MF的Oracle JDBC驱动程序版本

实现的版本:11.2.0.3.0
库ID:JAVAVM_11.2.0.4.0_LINUX.X64_130711



Answer 8:

经过反复试验。 这样的工作:

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

不过这样一来返回oraConnection空指针:

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


Answer 9:

下面的工作来解决AQ的TopicConnection.getTopicSession => JMS-112

//DEBUG: Native DataSource : weblogic.jdbc.common.internal.RmiDataSource
con = DataSource.getConnection();
debug("Generic SQL Connection: " + con.toString());               
//DEBUG: Generic Connection: weblogic.jdbc.wrapper.PoolConnection_oracle_jdbc_driver_T4CConnection
if (con != null && con.isWrapperFor(OracleConnection.class)) {
  WebLogicNativeJdbcExtractor wlne = new WebLogicNativeJdbcExtractor();//org.springframework to the rescue!!
  java.sql.Connection nativeCon = wlne.getNativeConnection(con);
  this.oraConnection = (OracleConnection) nativeCon;
  debug("Unwrapp SQL Connection: " + this.oraConnection.toString());
}

//DEBUG: Native Connection: oracle.jdbc.driver.T4CConnection è 

现在我可以在AQ-厂使用W / O JMS-112



Answer 10:

试图铸造象下面

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


文章来源: Connection cannot be cast to oracle.jdbc.OracleConnection