2016-04-13 10 views
0

Ich habe eine Java-Anwendung mit Hibernate 5.1.0, mit räumlichen Fähigkeiten (geolatte) auf Weblogic 12.1.1.0 und Oracle Datenbank ausgeführt. Ich habe einige Datenquellen konfiguriert mit Treiber oracle.jdbc.xa.client.OracleXADataSource. Dies funktioniert in einer Umgebung, aber nicht in einer anderen. Wenn eine Abfrage ausgeführt wird erhalte ich die folgende Stacktrace:Versuchte Abrufen von OracleConnection, aber null erhalten

org.hibernate.HibernateException: java.lang.RuntimeException: Tried retrieving OracleConnection from weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection using method getOriginalOwner, but received null. 
    at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.toNative(SDOGeometryValueBinder.java:88) 
    at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.bind(SDOGeometryValueBinder.java:53) 
    at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:253) 
(...) 
Caused by: java.lang.RuntimeException: Tried retrieving OracleConnection from weblogic.jdbc.wrapper.JTAConnection_weblogic_jdbc_wrapper_XAConnection_oracle_jdbc_driver_LogicalConnection using method getOriginalOwner, but received null. 
    at org.geolatte.geom.codec.db.oracle.DefaultConnectionFinder.find(DefaultConnectionFinder.java:75) 
    at org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory.createStruct(OracleJDBCTypeFactory.java:117) 
    at org.hibernate.spatial.dialect.oracle.SDOGeometryValueBinder.store(SDOGeometryValueBinder.java:72) 

Wenn ich einen Blick auf den Code in der geolatte-geom Bibliothek, die von Hibernate genannt wird sehe ich die DefaultConnectionFinder.java wie folgt:

for (Method method : con.getClass().getMethods()) { 
     if (method.getReturnType().isAssignableFrom(
       java.sql.Connection.class 
     ) 
       && method.getParameterTypes().length == 0) { 

      try { 
       method.setAccessible(true); 
       final Connection oc = find((Connection) (method.invoke(con, new Object[] { }))); 
       if (oc == null) { 
        throw new RuntimeException(
          String.format(
            "Tried retrieving OracleConnection from %s using method %s, but received null.", 
            con.getClass().getCanonicalName(), 
            method.getName() 
          ) 
        ); 
       } 
       return oc; 
      } 

Es ist Abrufen des von Weblogic bereitgestellten Verbindungswrappers und Iteration aller verfügbaren Methoden mithilfe von Reflektion. Es wird versucht, die tatsächliche Verbindung nach einer Methode abzurufen, die eine java.sql.Connection.class und keine Eingabeparameter zurückgibt.

Meine Vermutung ist, dass die meisten der Zeit fand die Methode getConnection aber in diesem Fall ist, wie getMethods() nicht die Werte in einer bestimmten Reihenfolge zurückkehrt, kann es der Fall sein, dass die getOriginalOwner Methode zuerst geht, die null zurückgibt, und die Ausnahme passiert.

Ich denke hier meine Frage ist, ob Sie denken, dass ich etwas falsch mache, und wie ich dies vermeiden kann, oder es ist ein Hibernate-Fehler und ich sollte die Verbindung zurückgeben, wenn es nicht null ist (wenn es null ist halten nur mit der Iteration) oder etwas ähnliches:

final Connection oc = find((Connection) (method.invoke(con, new Object[] { }))); 
if (oc != null) { 
    return oc; 
} 

Antwort

1

http://www.hibernatespatial.org/documentation/03-dialects/05-oracle/ für die Erklärung von dem, was Zweck ist der ConnectionFinder Schnittstelle. Wenn der DefaultConnectionFinder in Ihrer Umgebung nicht funktioniert, sollten Sie eine eigene Implementierung erstellen, die die richtige OracleConnection-Instanz zurückgibt, und sie mithilfe der Konfigurationseigenschaft hibernate.spatial.connection_finder konfigurieren.

+0

Hallo Karel Maesen, danke für die Antwort, ich denke, es bringt Mehrwert. Wie auch immer, ich frage mich, warum Sie eine RuntimeException auslösen würden, sobald Sie eine Methode finden, die möglicherweise eine Verbindung zurückgibt, aber nicht (wie im Fall von getOriginalOwner), anstatt den Rest der Kandidaten zu durchlaufen und zu überprüfen, ob Sie finden können ein besseres wie im Code-Snippet oben. Dies war Weblogic 12.1.1.0 mit dieser Race Condition, also dachte ich, dass diese Implementierung abgedeckt wäre. – krause