0

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;
}
krause
  • 436
  • 5
  • 24

1 Answers1

1

See http://www.hibernatespatial.org/documentation/03-dialects/05-oracle/ for the explanation of what purpose is of the ConnectionFinder interface.

If the DefaultConnectionFinder doesn't work in your environment, you should create your own implementation that returns the proper OracleConnection instance, and configure it using the hibernate.spatial.connection_finder configuration property.

Karel Maesen
  • 751
  • 5
  • 7
  • Hi Karel Maesen, thanks for the response, I think it adds value. Anyway I wonder why you would throw a RuntimeException as soon as you find a method that will potentially return a connection but it doesn't (as in the case of getOriginalOwner) instead of iterating through the rest of the candidates and check if you can find a better one as in the code snippet above. This was Weblogic 12.1.1.0 showing this race condition, so I thought this implementation would have been covered. – krause May 03 '16 at 09:40