---
title: Open session
summary: Chooses a stateful or stateless NHibernate session and the matching system-date session helper.
status: draft
owner: Framework
last_reviewed: 2026-10-02
library: SAIF.NetCore.NHibernate
reference_type: package
operation_id: OP-NH-06
trigger: UnitOfWorkFactory builds a new unit of work
---

# Open session

This operation selects and opens the NHibernate session for a new unit of work, choosing between a stateful (change-tracking) and stateless (bulk-throughput) strategy, and pairs it with the engine-appropriate system-date helper.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-NH-06 |
| **Trigger** | [Create unit of work](create-unit-of-work.md) calls `BuildSessionStrategy`/`BuildSessionHelper` while assembling a `UnitOfWork` |
| **Inputs** | `ISessionFactory`, `options.StatelessSessionStrategy`, `options.Database`, the factory's `debugOutputSql` flag |
| **Outputs** | An `ISessionStrategy` (`StatefulSessionStrategy` or `StatelessSessionStrategy`) and an `ISessionHelper` (`OracleSessionHelper`, `SqlServerSessionHelper`, or `PostgreSqlSessionHelper`) |
| **Primary components** | `UnitOfWorkFactory.BuildSessionStrategy`, `BuildSessionHelper` |
| **Entry point** | `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Factories/UnitOfWorkFactory.cs` |

## Steps

1. `BuildSessionStrategy(factory, options.StatelessSessionStrategy)` checks `options.StatelessSessionStrategy` ([BR-NH-10](../business-rules.md#br-nh-10-session-type-selected-by-statelesssessionstrategy-option)):
   - If `true`: return `new StatelessSessionStrategy(factory.OpenStatelessSession())`. No interceptor is ever applied on this path.
   - If `false`: 
     - If the factory's `debugOutputSql` is `true`: open the session with `factory.WithOptions().Interceptor(new SqlDebugOutputInterceptor()).OpenSession()` ([BR-NH-09](../business-rules.md#br-nh-09-sql-debug-interceptor-applies-only-to-stateful-sessions-while-debugging)). See [Debug SQL tracing](debug-sql-tracing.md) for how the interceptor behaves.
     - Otherwise: open the session with `factory.OpenSession()`.
     - Either way, wrap the resulting `ISession` in `new StatefulSessionStrategy(session)`.
2. `BuildSessionHelper(sessionStrategy, options)` switches on `options.Database` ([BR-NH-07](../business-rules.md#br-nh-07-unrecognized-database-type-falls-back-to-oracle)):
   - `Oracle` → `new OracleSessionHelper(strategy)`
   - `Sql` → `new SqlServerSessionHelper(strategy)`
   - `PostGreSql` → `new PostgreSqlSessionHelper(strategy)`
   - Any other value → `new OracleSessionHelper(strategy)`

## Process flow

The diagram below visualizes the stateless/stateful branch, the debug-interceptor sub-branch for stateful sessions, and the engine-selection branch for the matching session helper.

```mermaid
flowchart TD
	Start(["BuildSessionStrategy called"]) --> Stateless{"StatelessSessionStrategy?"}
	Stateless -->|Yes| OpenStateless["factory.OpenStatelessSession()"]
	Stateless -->|No| Debug{"debugOutputSql?"}
	Debug -->|Yes| OpenWithInterceptor["OpenSession() with<br>SqlDebugOutputInterceptor"]
	Debug -->|No| OpenPlain["factory.OpenSession()"]
	OpenStateless --> WrapStateless["new StatelessSessionStrategy"]
	OpenWithInterceptor --> WrapStateful["new StatefulSessionStrategy"]
	OpenPlain --> WrapStateful
	WrapStateless --> Helper["BuildSessionHelper(options.Database)"]
	WrapStateful --> Helper
	Helper --> Return(["Return ISessionStrategy + ISessionHelper"])
```

## Failure and edge-case behavior
- Stateless sessions never receive the SQL debug interceptor, regardless of `debugOutputSql` ([BR-NH-09](../business-rules.md#br-nh-09-sql-debug-interceptor-applies-only-to-stateful-sessions-while-debugging)).
- An unrecognized `options.Database` value falls back to the Oracle session helper, which issues Oracle-specific SQL (`select sysdate from dual`) against whatever engine the connection string actually points at — this can fail at runtime if the engine is not Oracle.*

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Sources
- `src/SAIF.NetCore.Nhibernate/SAIF.NetCore.NHibernate/SAIF.NetCore.NHibernate/Factories/UnitOfWorkFactory.cs`
