I have a Java application using Hibernate 5.1.0
, with spatial capabilities (geolatte
) running on Weblogic 12.1.1.0
and Oracle
database. I have some data sources configured with driver oracle.jdbc.xa.client.OracleXADataSource
. This works ok in one environment, but not in another. When running a query I get the following stacktrace :
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)
When I have a look at the code in the geolatte-geom
library that is called by Hibernate I see the DefaultConnectionFinder.java as below :
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;
}
It is getting the connection wrapper provided by Weblogic and iterate through all the available methods using reflection. It will try to retrieve the actual connection looking for a method which returns a java.sql.Connection.class
and no input parameters.
My guess is that most of the times the method found is getConnection
but in this case, as getMethods()
does not return the values in a particular order, it can be the case that the getOriginalOwner
method goes first, which returns null, and the exception happens.
I guess here my question is whether you think I'm doing something wrong, and how I can avoid this, or it is a Hibernate error and I should return the connection when it is not null (when it is null I will just keep on with the iteration) or something similar :
final Connection oc = find( (Connection) ( method.invoke( con, new Object[] { } ) ) );
if ( oc != null ) {
return oc;
}