Jdbc 通过JOOQ meta访问H2元模型时发生SQLException

Jdbc 通过JOOQ meta访问H2元模型时发生SQLException,jdbc,h2,jooq,Jdbc,H2,Jooq,我正在尝试使用JOOQ的DSLContext.meta(),获取内存数据库中H2中所有表的列表: 结果: java.lang.RuntimeException: org.jooq.exception.DataAccessException: Error while accessing DatabaseMetaData at MyTest.deleteEntities(MyTest.java:222) at MyTest.cleanupDatabase(My

我正在尝试使用JOOQ的
DSLContext.meta()
,获取内存数据库中H2中所有表的列表:

结果:

    java.lang.RuntimeException: org.jooq.exception.DataAccessException: Error while accessing DatabaseMetaData
        at MyTest.deleteEntities(MyTest.java:222)
        at MyTest.cleanupDatabase(MyTest.java:201)
        at MyTest.afterTestCase(MyTest.java:117)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        [... omitted for brevity ...]
    Caused by: org.jooq.exception.DataAccessException: Error while accessing DatabaseMetaData
        at org.jooq.impl.MetaImpl.getCatalogs(MetaImpl.java:160)
        at org.jooq.impl.MetaImpl.getSchemas(MetaImpl.java:168)
        at org.jooq.impl.MetaImpl.getTables(MetaImpl.java:179)
        at MyTest.deleteEntities(MyTest.java:210)
        ... 29 more
    Caused by: org.h2.jdbc.JdbcSQLException: The object is already closed [90007-174]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
        at org.h2.message.DbException.get(DbException.java:172)
        at org.h2.message.DbException.get(DbException.java:149)
        at org.h2.message.DbException.get(DbException.java:138)
        at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1410)
        at org.h2.jdbc.JdbcConnection.checkClosed(JdbcConnection.java:1388)
        at org.h2.jdbc.JdbcDatabaseMetaData.checkClosed(JdbcDatabaseMetaData.java:2963)
        at org.h2.jdbc.JdbcDatabaseMetaData.getCatalogs(JdbcDatabaseMetaData.java:756)
        at org.jooq.impl.MetaImpl.getCatalogs(MetaImpl.java:143)
        ... 32 more
DSL\u CONTEXT\u PROVIDER.db()
如下所示:

JdbcDataSource h2ds = new JdbcDataSource();
h2ds.setURL("jdbc:h2:mem:testDB;create=true");
h2ds.setUser("");
h2ds.setPassword("");
return DSL.using(new DefaultConfiguration().set(new DataSourceConnectionProvider(h2ds)));
普通查询可以使用上述配置,但不能使用
meta().getTables()
。如果用不关闭连接的匿名实现替换
DataSourceConnectionProvider
,则不会再引发异常


似乎H2不赞成在关闭基础连接后对
connection.getMetaData()
返回的对象调用
getCatalogs()
之类的方法。这是
jooq-meta
(我使用的是3.7.0)中的错误还是我的配置有缺陷

jOOQ 3.7.0/3.7.1及更早版本正在
org.jOOQ.Meta
中缓存
数据库元数据。这是一个bug(),将很快修复

您遇到此问题的原因是因为您使用的是
数据源连接提供程序
,它实际上不适用于独立连接或“简单的”
数据源
。它在每次查询后关闭连接(通常转换为将其返回池)。关闭连接后,缓存的
数据库元数据
引用已过时

您已经记录了解决方法:不要将“简单的”
DataSource
与jOOQ的
DSLContext.meta()
API一起使用

JdbcDataSource h2ds = new JdbcDataSource();
h2ds.setURL("jdbc:h2:mem:testDB;create=true");
h2ds.setUser("");
h2ds.setPassword("");
return DSL.using(new DefaultConfiguration().set(new DataSourceConnectionProvider(h2ds)));