it-swarm.com.de

Die Verbindung kann nicht in Oracle.jdbc.OracleConnection umgewandelt werden

Warum kann Java.sql.Connection nicht im folgenden Code in Oracle.jdbc.OracleConnection umgewandelt werden?

Mein Hauptziel ist es, einen neuen Benutzernamen an die Oracle-Verbindung zu übergeben und ihn in der 'SESSION'-Tabelle in der' osuser'-Spalte zu speichern, da ich in DB-Benutzeränderungen nachverfolgen und sie in der Tabelle anzeigen möchte.

@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();
        }
    }
}

Hier ist ein Fehlerprotokoll:

10:42:29,251 INFO  [STDOUT] [email protected]b
10:42:51,701 ERROR [STDERR] Java.lang.ClassCastException: $Proxy286 cannot be cast to Oracle.jdbc.OracleConnection

Im Allgemeinen habe ich in diesem Fall 2 Probleme:

  • warum die Umwandlung von Connection zu OracleConnection fehlschlägt und
  • was ist der beste Weg, um meine Absicht zu implementieren?

Ich arbeite mit Oracle 11g, Hibernate (mit Entitätsmanager), Datenquelle über Jndi.

Bitte helfen, danke!

BEARBEITEN:

Nach einigen Verbesserungen besteht das Problem noch beim Gießen.

Verbesserung:

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

Error:

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

Die Verbindung, die Sie abrufen, ist wahrscheinlich eine umschlossene Verbindung.

Wenn Sie wirklich die zugrunde liegende Oracle-Verbindung benötigen, sollten Sie Folgendes verwenden:

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

Die isWrapperFor- und unwrap-Methoden sind seit Java 1.6 verfügbar und sollten von den A/S-Verbindungswrappern sinnvoll implementiert werden.

34

Der Verbindungspool hat normalerweise einen Wrapper um die reale Verbindungsinstanz, daher schlägt Ihre Umwandlung fehl. 

Was Sie tun, funktioniert sowieso nicht, weil die Parameter in der Eigenschafteninstanz nur geprüft werden, wenn die Verbindung hergestellt ist. Da Sie bereits eine Verbindung haben, ändert sich dadurch nichts. 

Sie müssen DBMS_APPLICATION_INFO.SET_CLIENT_INFO() verwenden, um dies für eine bestehende Verbindung zu ändern.

Dies ist nur für Leute, die über die Suche nach Metriken in OracleConnection hierher kommen. Ich verbringe viel Zeit damit, also könnte jemandem helfen.

Nachdem Sie Ihre "Verbindung" erhalten haben, sollte dies funktionieren:

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...

Es funktioniert für OracleConnection, aber ich habe ein Problem mit dem Festlegen von Metriken:

short zero = 0;
oraConnection.setEndToEndMetrics(metrics, zero);

Nach dem Verbindungsaufbau über meine Methode, bei der ich einige Male Metriken eingestellt habe, erhalte ich Folgendes:

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

Aber ich denke, es hat etwas mit Spring-Verdrahtungseinsätzen oder Verbindungspools zu tun.

2
Jenya G

ich war mit diesem Problem konfrontiert, als ich den Frühling benutzte, um Verbindungen herzustellen. Normalerweise fügt jede Ebene den Grundklassen einen Wrapper hinzu. Ich hatte gerade connection.getClass (). getName () gemacht, um den Laufzeittyp der Verbindung zu sehen, die erneut abgestimmt wird. Es wird ein Wrapper/Proxy sein, über den Sie leicht die Methode finden können, um den Basis-OracleConnection-Typ zu erhalten. 

1
Akhilesh Singh

Sie können auf das innere OracleObject in einem Wrapper zugreifen. In diesem Fall lautet der Wrapper-Typ NewProxyConnection:

(Ich habe es in meinem Projekt verwendet, es hat funktioniert ... kein Geheimnis, einfach Reflexion verwenden)

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;
 }
1
Ricuzzo

Nach Versuch und Irrtum. Dieser Weg funktioniert:

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

Auf diese Weise wurde jedoch ein Nullzeiger für oraConnection zurückgegeben:

DelegatingConnection delConnection = (DelegatingConnection) dbcpConnection;
    oraConnection = (Oracle.jdbc.OracleConnection)delConnection.getInnermostDelegate();
0
frva

Ich bin nicht sicher, ob meine Situation verwandt ist, aber bei meinem Projekt führt das einfache Ändern einer Datenbankkonfigurationseinstellung tatsächlich dazu, dass das Entpacken fehlschlägt!

Ich benutze das Play-Framework mit Scala. das funktioniert bei mir nur wenn logSql = false:

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

(dies ist nur die Scala-Version zum Entpacken einer OracleConnection)

Wenn ich logSql = true setze, erhalte ich:

com.Sun.proxy. $ Proxy17 kann nicht in Oracle.jdbc.OracleConnection .__ umgewandelt werden. Java.lang.ClassCastException: com.Sun.proxy. $ Proxy17 kann nicht in .__ umgewandelt werden. Oracle.jdbc.OracleConnection

Also kann etwas über die logSql-Konfiguration dazu führen, dass das Unwrap fehlschlägt. Keine Ahnung warum.

Bei jeder Konfiguration lautet mein Verbindungsobjekt:

HikariProxyConnection @ 1880261898 Wrapping [email protected]

isWrapperFor(OracleConnection) ist in beiden Fällen wahr

Dies geschieht mit dem Hikari Connection Pool und dem Bone-CP. Vielleicht ist es ein Fehler in Oracle JDBC?

Oracle JDBC-Treiberversion gemäß MANIFEST.MF

Implementierungsversion: 11.2.0.3.0
Repository-Id: JAVAVM_11.2.0.4.0_LINUX.X64_130711

0
Arlo

Versuche Folgendes

Ich war auf das gleiche Problem gestoßen. Wir haben spring verwendet und es gibt eine Klasse namens NativeJdbcExtractor. Es gibt viele Implementierungen und die folgende funktioniert für Tomcat. Es gibt eine spezielle Implementierung für Jboss, den JBossNativeJdbcExtractor

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

In Ihrem DAO können Sie die Bohne injizieren und die folgende Methode verwenden

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