【问题标题】:Tried retrieving OracleConnection but received null尝试检索 OracleConnection 但收到 null
【发布时间】:2016-04-13 17:45:40
【问题描述】:

我有一个使用 Hibernate 5.1.0 的 Java 应用程序,在 Weblogic 12.1.1.0 和 Oracle 数据库上运行空间功能 (geolatte)。我有一些配置了驱动程序oracle.jdbc.xa.client.OracleXADataSource 的数据源。这在一种环境中可以正常工作,但在另一种环境中则不行。运行查询时,我得到以下堆栈跟踪:

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)

当我查看 Hibernate 调用的 geolatte-geom 库中的代码时,我看到 DefaultConnectionFinder.java 如下:

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

它正在获取 Weblogic 提供的连接包装器,并使用反射遍历所有可用的方法。它将尝试检索实际连接,寻找返回java.sql.Connection.class 且没有输入参数的方法。

我的猜测是大多数时候找到的方法是getConnection,但在这种情况下,由于getMethods() 不会按特定顺序返回值,因此可能是getOriginalOwner 方法先行,它返回null,并且发生异常。

我想我的问题是你是否认为我做错了什么,以及如何避免这种情况,或者它是一个 Hibernate 错误,我应该在它不为空时返回连接(当它为空时,我会继续迭代)或类似的东西:

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

【问题讨论】:

    标签: java oracle hibernate weblogic12c hibernate-5.x


    【解决方案1】:

    有关 ConnectionFinder 接口用途的说明,请参阅 http://www.hibernatespatial.org/documentation/03-dialects/05-oracle/。

    如果 DefaultConnectionFinder 在您的环境中不起作用,您应该创建自己的实现来返回正确的 OracleConnection 实例,并使用 hibernate.spatial.connection_finder 配置属性对其进行配置。

    【讨论】:

    • 嗨 Karel Maesen,感谢您的回复,我认为它增加了价值。无论如何,我想知道为什么你会在找到可能返回连接但它不返回连接的方法时立即抛出 RuntimeException(如 getOriginalOwner 的情况),而不是遍历其余候选者并检查是否可以找到一个更好的,如上面的代码 sn-p。这是显示这种竞争条件的 Weblogic 12.1.1.0,所以我认为这个实现会被覆盖。
    猜你喜欢
    • 2014-07-21
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    相关资源
    最近更新 更多