简体   繁体   中英

Tried retrieving OracleConnection but received null

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM