0

我正在使用 groovy.sql.Sql 对 Oracle 执行查询并返回一个 ResultSet,然后在自定义 TableAdapter 中使用它来支持 JTable。查询执行没有错误,但是当我尝试从 ResultSet 中检索 MetaData 时,在第 72 行的 OracleResultSetMetaData 的 <init> 方法期间抛出 NullPointerException。我无法找到该类的源代码以找出什么可能为空,所以我向这个很棒的社区寻求帮助。

下面的函数是我用来执行我的 SQL 查询的函数,该查询是在解析模板的单独类中生成的。我目前正在模拟模板以返回经过验证的有效 SQL 语句。

ResultSet getResultSet() {
    if (data == null) {
        if (sql == null) {
            sql = Sql.newInstance(CONN_STRING, USERNAME, PASSWORD, DRIVER_NAME)
            sql.resultSetType = ResultSet.TYPE_SCROLL_SENSITIVE
            sql.resultSetHoldability = ResultSet.HOLD_CURSORS_OVER_COMMIT // Added since initial post
        }

        data = sql.executeQuery(template.getSql())          
    }

    return data
}

我的 getColumnCount 方法是发生 NPE 的地方,它看起来像这样。

@Override
public synchronized int getColumnCount() {
    return getResultSet().metaData.columnCount
}

这是我的堆栈跟踪,可以很好地衡量。

2012-10-20 21:49:12,135 [AWT-EventQueue-0] ERROR org.codehaus.griffon.runtime.builder.UberBuilder - An error occurred while building browser.BrowserView@17c1e333
 [exec] java.lang.NullPointerException
 [exec]     at oracle.jdbc.driver.OracleResultSetMetaData.<init>(OracleResultSetMetaData.java:72)
 [exec]     at oracle.jdbc.driver.ScrollableResultSet.getMetaData(ScrollableResultSet.java:2004)
 [exec]     at com.trxi.browser.TemplateTableModel.getColumnCount(TemplateTableModel.groovy:75)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeFactoryMethod(UberInterceptorMetaClass.groovy:97)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.this$3$invokeFactoryMethod(UberInterceptorMetaClass.groovy)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass$this$3$invokeFactoryMethod.callCurrent(Unknown Source)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeMethod(UberInterceptorMetaClass.groovy:141)
 [exec]     at browser.BrowserView$_run_closure1_closure2.doCall(BrowserView.groovy:11)
 [exec]     at browser.BrowserView$_run_closure1_closure2.doCall(BrowserView.groovy)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeFactoryMethod(UberInterceptorMetaClass.groovy:97)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.this$3$invokeFactoryMethod(UberInterceptorMetaClass.groovy)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass$this$3$invokeFactoryMethod.callCurrent(Unknown Source)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeMethod(UberInterceptorMetaClass.groovy:141)
 [exec]     at browser.BrowserView$_run_closure1.doCall(BrowserView.groovy:10)
 [exec]     at browser.BrowserView$_run_closure1.doCall(BrowserView.groovy)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeFactoryMethod(UberInterceptorMetaClass.groovy:97)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.this$3$invokeFactoryMethod(UberInterceptorMetaClass.groovy)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass$this$3$invokeFactoryMethod.callCurrent(Unknown Source)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeMethod(UberInterceptorMetaClass.groovy:168)
 [exec]     at browser.BrowserView.run(BrowserView.groovy:4)
 [exec]     at org.codehaus.griffon.runtime.builder.UberInterceptorMetaClass.invokeMethod(UberInterceptorMetaClass.groovy:152)
 [exec]     at org.codehaus.griffon.runtime.builder.UberBuilder.build(UberBuilder.groovy:160)
 [exec]     at org.codehaus.griffon.runtime.core.AbstractMVCGroup$1.run(AbstractMVCGroup.java:129)

更新:我修改了我的代码以从模板而不是 ResultSetMetaData 对象中提取信息,现在我收到一个错误,即我的 ResultSet 已关闭。我认为假设这是导致 OracleResultSetMetaData 对象在其 <init> 方法期间失败的原因是相对安全的。谁能看到我做错了什么?

4

1 回答 1

0

经过一番研究,我发现 ResultSet 被关闭的原因是正在 groovy.sql.Sql.executeQuery() 函数的底层创建的 Statement 对象正在被关闭。为了防止它被关闭,我只需要在我的 groovy.sql.Sql 对象上启用语句缓存。

sql.cacheStatements = true
于 2012-10-21T05:19:08.767 回答