title: Abandoned H2 connection involving linked table
body: <p>I'm having trouble with an application using H2, seemingly due to database connections being left open. I'm trying to understand if it's H2 leaking the connection or me (I'm aware that it's more likely to be me).</p>
  
  <p>The application has Component1, which creates an in-memory H2 database and starts a TCP server. The H2 database contains a few <a href="http://www.h2database.com/html/advanced.html#linked_tables" rel="nofollow noreferrer">linked tables</a> which connect to a separate Oracle database using its JNDI identifier. Component2 connects to this database using JDBC with URL <code>jdbc:h2:tcp://127.0.1.1:5521/mem:db1;</code>.</p>
  
  <p>In the exception below I've highlighted where I'm getting confused. The trace seems to say that a query was issued by a TCP client (Component2) that required a query of a linked table, and that the query on the linked table is what left the connection open. I do not control how H2 connects to the linked table via JNDI, so I'm inclined to think this is not my fault. I've included a linked table definition below the exception to show how they are created.</p>
  
  <p>Can someone please help me understand who - between me and H2 - is responsible for this abandoned connection, and why?</p>
  
  <p><strong>Exception</strong></p>
  
  <pre><code>org.apache.tomcat.dbcp.dbcp.AbandonedTrace$AbandonedObjectException: DBCP object created 2019-12-10 05:46:16 by the following code was never closed:
      at org.apache.tomcat.dbcp.dbcp.AbandonedTrace.setStackTrace(AbandonedTrace.java:139)
      at org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:81)
      at org.apache.tomcat.dbcp.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
      at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
      at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:311)
      at org.h2.util.JdbcUtils.getConnection(JdbcUtils.java:274)
      at org.h2.table.TableLinkConnection.open(TableLinkConnection.java:89)
      at org.h2.table.TableLinkConnection.open(TableLinkConnection.java:76)
      at org.h2.engine.Database.getLinkConnection(Database.java:2708)
  --&gt; at org.h2.table.TableLink.connect(TableLink.java:96)
      at org.h2.table.TableLink.execute(TableLink.java:535)
      at org.h2.index.LinkedIndex.find(LinkedIndex.java:129)
      at org.h2.index.BaseIndex.find(BaseIndex.java:132)
      at org.h2.index.IndexCursor.find(IndexCursor.java:163)
      at org.h2.table.TableFilter.next(TableFilter.java:475)
      at org.h2.command.dml.Select$LazyResultQueryFlat.fetchNextRow(Select.java:1882)
      at org.h2.result.LazyResult.hasNext(LazyResult.java:101)
      at org.h2.result.LazyResult.next(LazyResult.java:60)
      at org.h2.command.dml.Select.queryFlat(Select.java:742)
      at org.h2.command.dml.Select.queryWithoutCache(Select.java:884)
      at org.h2.command.dml.Query.queryWithoutCacheLazyCheck(Query.java:151)
      at org.h2.command.dml.Query.query(Query.java:435)
      at org.h2.command.dml.Query.query(Query.java:397)
      at org.h2.command.CommandContainer.query(CommandContainer.java:145)
      at org.h2.command.Command.executeQuery(Command.java:202)
      at org.h2.server.TcpServerThread.process(TcpServerThread.java:335)
  --&gt; at org.h2.server.TcpServerThread.run(TcpServerThread.java:175)
      at java.lang.Thread.run(Thread.java:745)
  </code></pre>
  
  <p><strong>Linked Table</strong></p>
  
  <pre><code>CREATE LINKED TABLE ora_table (
    'javax.naming.InitialContext',
    'java:comp/env/jdbc/oradb',
    NULL,
    NULL,
    '(
      SELECT field
        FROM table
     )'
  )
  </code></pre>