Skip to content

Test connection

This operation gives consumers a lightweight connectivity smoke test that exercises the real transaction lifecycle (not just "can I open a connection") against a mapped entity type.

Field Value
Operation ID OP-NH-13
Trigger Consumer calls IUnitOfWork.TestConnection<TEntity>()
Inputs TEntity — any mapped entity type
Outputs No return value; throws if the connection, mapping, or transaction lifecycle fails
Primary components UnitOfWork.TestConnection<TEntity>
Entry point src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs

Steps

  1. Call Begin transaction (this.Begin()), which opens a ReadCommitted transaction (BR-NH-11)

Origin: The transaction-start logic reached here is implemented in Begin transaction. That operation's steps 1–3 (throw InvalidOperationException if a transaction is already active/committed/rolled back; otherwise call Session.Clear() — a no-op on a stateless session, a first-level-cache discard on a stateful session; then call Session.BeginTransaction(IsolationLevel.ReadCommitted)) run here, on this operation's behalf, before the query in step 2 executes. 2. Call this.GetRepository<TEntity>().Query().Where(x => false).ToList() — this builds and executes a LINQ-to-NHibernate query with a constant-false predicate, translated to SQL with a WHERE clause that can never match any row (SQL-004). The query still requires TEntity to be validly mapped and the connection/transaction to be functional. 3. Call Commit (this.Commit()), which requires the transaction opened in step 1 to still be active (BR-NH-13)

Origin: The commit logic reached here is implemented in Commit. That operation's steps 1–4 (throw InvalidOperationException if no transaction is active; otherwise call transaction.Commit(), issuing a database COMMIT and, for a stateful session, an auto-flush of pending changes subject to the session's FlushMode; then call Session.Clear() — a no-op on a stateless session, a first-level-cache discard on a stateful session) run here, on this operation's behalf, to finish this operation's begin/query/commit cycle.

Process flow

The diagram below visualizes the begin/query/commit sequence this operation chains together.

flowchart TD
    Start(["TestConnection<TEntity>() called"]) --> Begin["Begin()"]
    Begin --> Query["GetRepository<TEntity>().Query()<br>.Where(x => false).ToList()"]
    Query --> Commit["Commit()"]
    Commit --> Return(["No exception = connection OK"])

Failure and edge-case behavior

  • Any failure in Begin, the query translation/execution, or Commit propagates as an exception — there is no try/catch inside TestConnection; callers must handle failures themselves.
  • Because this runs the full Begin/Commit cycle, calling it while the unit of work already has an active transaction throws InvalidOperationException from Begin (BR-NH-12). After it completes successfully, the session's transaction has been committed and detached, so the same unit of work can begin another transaction (NHibernate 5.2.7).
  • The constant-false predicate means zero rows are ever returned regardless of table contents; this call never touches real data, only connectivity/mapping/transaction plumbing.

Sources

  • src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/UnitOfWork.cs