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