Class TestScopedConnection

java.lang.Object
org.dbunit.database.connection.TestScopedConnection

public final class TestScopedConnection extends Object
One connection acquired to serve a single test's dbUnit lifecycle: acquired at most once from a supplier, memoized so every step of that test reuses it rather than opening its own, and released at the end only when this lifecycle - not some external owner - is the one that should close it, as its ConnectionOwnership decides.

Not thread-safe; a test's steps run sequentially on one thread.

Since:
3.6.0
Author:
Jeff Jensen
  • Constructor Details

    • TestScopedConnection

      public TestScopedConnection(Callable<IDatabaseConnection> source, ConnectionOwnership ownership, Consumer<IDatabaseConnection> onAcquired)
      Creates a test-scoped connection.
      Parameters:
      source - Acquires the connection on first use; may return null (e.g. a test double with no connection to offer).
      ownership - Decides, at release() time, whether this lifecycle may close the connection.
      onAcquired - Run once on each connection source returns, immediately after acquisition (e.g. to apply @DbUnitProperty values, or warn on an autocommit-off connection); not run for a null connection, nor for one adopt(IDatabaseConnection) takes over. May be null.
  • Method Details

    • getConnection

      public IDatabaseConnection getConnection() throws Exception
      Returns the connection for this test, acquiring it from the supplier on first use and returning the same one thereafter. A memoized connection that has since been closed - by a pool max-lifetime, a server reap, a CachingConnectionProvider.close() between reused test methods - is dropped and re-acquired rather than handed back dead.
      Returns:
      The connection, or null when the supplier has none to offer.
      Throws:
      Exception - If the supplier fails.
    • peekConnection

      public IDatabaseConnection peekConnection()
      Returns the connection already acquired this test, or null both before getConnection() first runs and when the supplier had none - never triggers acquisition.
      Returns:
      The memoized connection, or null.
    • isResolved

      public boolean isResolved()
      Returns whether getConnection() or adopt(IDatabaseConnection) has run this test, regardless of whether the resulting connection is null.
      Returns:
      true once a connection (possibly null) has been resolved.
    • adopt

      public void adopt(IDatabaseConnection connection)
      Takes over a connection acquired elsewhere - the executor's listener piggyback, which memoizes whatever connection the tester's own onSetup() retrieved - as if getConnection() had returned it. onAcquired is not run: the caller doing the piggyback has already done that connection's post-acquisition setup.
      Parameters:
      connection - The connection to adopt.
    • release

      public void release() throws Exception
      Closes the connection when ConnectionOwnership.mayClose() allows it and it is not already closed; a no-op when no connection was ever acquired. Leaves the memo in place - a single-use holder is discarded with its owner, and a reused one relies on revalidateOnReacquire to drop the now-closed connection on the next getConnection().

      When it does close, it forgets the connection too, so the next getConnection() on a reused holder acquires a fresh one. When ownership says leave it - closeConnectionAfterTest=false, a no-op listener - the memo is kept for its real owner.

      The already-closed guard matters when this holder's connection is the same object another owner also closes - the @DbUnitExpected path, where the executor's borrowed connection and DefaultPrepAndExpectedTestCase's are one and the same. A null underlying JDBC connection is treated as nothing to close, the same way getConnection()'s liveness check does; a SQLException from the check is left to propagate rather than swallowed: a connection whose isClosed() throws has failed in a way worth surfacing (as a suppressed exception, via releaseSuppressing(Throwable)).

      An uncommitted transaction is rolled back first when the connection's autocommit is off - see rollBackOpenTransaction(Connection).

      Throws:
      Exception - If closing the connection, or checking whether it is already closed, fails.
    • releaseSuppressing

      public void releaseSuppressing(Throwable primary)
      Releases the connection, attaching any close failure to primary via Throwable.addSuppressed(Throwable) rather than letting it replace the more useful failure already in flight, then discards the memo.
      Parameters:
      primary - The failure already being thrown, to attach a close failure to.
    • discardOnFailure

      public void discardOnFailure()
      Forgets the memoized connection so the next getConnection() acquires a fresh one. For use after a lifecycle step failed: the step that just threw may have left the connection broken, so the next step should not reuse it.